我有 81 个 .fasta 格式的文件,其中包含(最多)53 个项目。例如:
/User/MyData/Sample_1.fasta
/User/MyData/Sample_2.fasta
....
/User/MyData/Sample_81.fasta
每个 .fasta 文件包含一个名称 ID 和分隔如下的字符串:
>AT1G00001
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>AT2G00002
AAAAATTTTGCCCGTGTGGGCCAAACTGTCATGCATGCACCGTACGTGCATGCAT
....
>ATXGXXXXX(up to 53)
AAACCCTCTTTGTGCCTGTGCATGCA
我想将 81 个 .fasta 文件中的每个字符串复制到一个新的 .fasta 文件中,以便:
/User/MyData/AT1G00001.fasta
/User/MyData/AT2G00002.fasta
....
/User/MyData/ATXGXXXXX.fasta
其中之一的内容包含(从目录中的所有“Sample_X.fasta”文件复制后):
>Sample_1
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>Sample_2
ATCGACTCCCGTAGGACTGATTTTTCTGACCCCATTGTGACACTGTG
....
>Sample_81
TTCTGACCCCATTGTGACACTGTGATCGACTCCCGTAGGACTGATTT
我遇到过一两个类似的问题,但与在复制的输出文件中保留 SampleName 的细微差别没有什么区别,并且我在从类似但不同的问题中获取示例时遇到一些困难。
非常感谢您的帮助!
答案1
我为您准备了以下代码;下面有一个解释它是如何工作的。
首先进入工作目录(cd /User/MyData/
)运行该程序:
awk '
FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
/^>/ { target = substr($0,2)".fasta" ; next }
{ print ">" sample > target ; print > target }
' Sample_*.fasta
该awk
程序迭代所有Sample_*.fasta
文件。在每个输入文件 ( ) 的开头,FNR==1
它通过删除后缀“.fasta”从当前文件名中提取样本名称。如果一行以 开头,>
则该记录的目标文件名取自该>
字符之后,并附加文件名后缀“.fasta”。对于其他类型的行,先前提取的样本名称将写入目标文件,并在第二行中写入当前数据。
注意:如果您发现“打开文件描述符太多”的问题,那么最好的选择是切换到 GNU(awk
如果可能)!
如果 GNUawk
没有或不能在您的平台上可用,那么您需要进行一些额外的更改;关键是使用该函数在写入每个文件后关闭每个文件close()
,结果是您必须附加到已关闭的文件。 (这更复杂,性能也较差,因此值得考虑获取 GNUawk
并使用第一个变体。)
这些更改将产生如下程序:
# because of the append operation you need to empty the file targets
# before calling subsequent awk code, e.g. by: rm -f AT???????.fasta
awk '
FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
/^>/ { target = substr($0,2)".fasta" ; next }
{ printf ">%s\n%s\n", sample, %0 >> target ; close(target) }
' Sample_*.fasta
请注意,在调用该awk
程序之前,您必须确保从先前的调用中删除或清空任何现有的输出文件(否则您的新输出将被附加到先前存在于相应输出文件中的数据中。
答案2
尽管了解您到目前为止所尝试过的内容会很有趣,但这里有一个如何awk
用于这项工作的示例:
awk '
FNR == 1 {
sub(/\.fasta$/, "", FILENAME)
}
/^>/ && sub(/^>/, "") {
newfile = $0 ".fasta"
next
}
{
print ">" FILENAME >> newfile
print $0 >> newfile
}' Sample_*.fasta
答案3
一些 shell:这会比 awk 程序慢得多。
cd /User/MyData
for sample in Sample*.fasta; do
sample_name=${sample%.fasta}
while read name; read data; do
name=${name#>}
printf ">%s\n%s\n" "$sample_name" "$data" >> "$name.fasta"
done < "$sample"
done