我有 28 个文件,每个文件都有大约 14,000 个“条目”。单个条目由一个标头(用 >string 表示)、一个换行符和一个字符串序列组成。每个条目都有可变长度的序列/字符串。所有 28 个文件都有相同的条目标头,但每个条目的顺序是可变的。
例如,一个文件 CR1_ref.fasta 看起来像
>FBgn0080937
ATGGATAAAAGGCTCAGCGATAGTCCCGGAGATTGTCGCGTAACCAGATCCAGCATGACGCCCACCCTCCGCTTGGAGCACAGTCCCCGGCGGCAACAACAGCAACAACA
>FBgn0076379
ATGCTGCGCACCCTTTTCGCCGTGCGTGGTCAGTGCCAGCAGCTGCTGAGGAGAACATTCACCCCCCATTGCAGTGGCCAACGA
>FBgn0070974
ATGCAGACGCGTCCGAGCAGTGAACCGCAGCGCGCCAAGGAGCAACTCCTGCGGGAGCTGCCGCCGCAGAAATGCTCCAGCGCCACGCTGGCCAAGAAGGTGCTGTCGCAGAGCCCGCCGGCAGCCCCGCCGCCCACACCGGCCACAATTGTGCCGCTCACTGCGGTGCCCGTCATCCAGCTGACGCCTCCGTCGCACTCCGGCGACACGCCGCAAAAGCCAGCACCTCCGGCGCCGCCGCCGCC
总体目标是创建约 14,000 个新文件。其中每个文件都是与所有 28 个文件中的特定 ID/标头关联的条目。
要从单个文件中提取单个条目,我可以使用以下命令
sed -n '/^>FBgn0080937$/{p;n;p;}' CR1_ref.fasta
要在所有 28 个文件中提取此条目(每个文件都以 ref.fasta 结尾),我可以这样做
for i in *ref.fasta; do sed -n '/^>FBgn0080937$/{p;n;p}' $i; done > FBgn0080937.fasta
我有一个单独的文本文件,每行有 14,000 行,对应于名为gene.txt 的条目的标题。该文件的前几行看起来像
FBgn0080937
FBgn0076379
FBgn0070974
FBgn0081668
FBgn0076576
FBgn0076572
FBgn0079684
FBgn0070907
FBgn0080226
FBgn0072746
我想通读该文件,为每个标头 ID 创建一个新的文本文件。 $F 下面提取特定标头 (FBgn*) 的条目并将其存储在新文件中。我正在使用替换命令根据它们来自的 while ref.fasta 文件来重命名序列。
while read -r line;
do F=$line
for i in *ref.fasta
do sed -n "/^>$F$/{s/FB.*/$i/;p;n;p;}" $i > $line.fasta
done
done < "gene.txt"
目前该脚本创建了 14,000 个文件,但每个文件只有一个序列。
>Z9_ref.fasta
ATGCAGACGCGTCCGAGCAGTGAACCGCAGCGCGCCAAGGAGCAAC
我期望每个 *ref.fasta 文件有 28 个序列一个序列。 sed 命令正在输出最后一个条目。预期输出是
>CR1_ref.fasta
ATGCAGACGCGTCCGAGCAGTGAACC
>FH2_ref.fasta
AGCAGTGAACCGCAGCGCGCCAAGGAGCAAC
>MSH10_ref.fasta
CGCGTCCGAGCAGTGAACCGCAGCGCGCCAAGGAGCAAC
>Z9_ref.fasta
ATGCAGACGCGTCCGAGCAGTGAACCGCAGCGCGCCAAGGAGCAAC
答案1
shell 并不真正适合这种类型的解析。您可以在自己的代码中看到,您读取了整个文件一次每个从文件中读取的基因名称gene.txt
。
下面的单个awk
命令可以更快地完成同样的事情。
awk -F '>' '
FNR == NR { genes[$1]; next }
/^>/ && $2 in genes { if (out != "") close(out);
out = $2 ".fa"
split(FILENAME, a, "_")
$0 = ">" a[1] "_" $2 }
out != "" { print >>out }' genes.txt *_ref.fasta
首先读取genes.txt
文件并创建一个从中调用的关联数组,genes
其中基因名称作为键。
当它到达 Fasta 文件时(代码假设这些文件都被称为类似的东西XXX_ref.fasta
),当我们读取 Fasta 标头,并且标头中的基因是我们列表中的键时genes
,然后我们从基因名称创建一个输出文件名asgenename.fa
并重写标头以包含当前文件名下划线之前的部分。
如果原始标头XXX_ref.fasta
是
>genename
那么这将被转化为
>XXX_genename
脚本的最后一部分awk
将所有行发送到适当的输出文件。
使用您提供的数据进行测试会生成三个文件:
$ ls *.fa
FBgn0070974.fa FBgn0076379.fa FBgn0080937.fa
$ cat FBgn0076379.fa
>CR1_FBgn0076379
ATGCTGCGCACCCTTTTCGCCGTGCGTGGTCAGTGCCAGCAGCTGCTGAGGAGAACATTCACCCCCCATTGCAGTGGCCAACGA