我有一个目录,其中包含多个 fasta 文件,名称如下:
BC-1_bin_1_genes.faa
BC-1_bin_2_genes.faa
BC-1_bin_3_genes.faa
BC-1_bin_4_genes.faa
等等。 (约200个单独文件)
fasta 标题看起来像这样:
>BC-1_k127_3926653_6 # 4457 # 5341 # -1 # ID=2_6;partial=01;start_type=Edge;rbs_motif=None;rbs_spacer=None;gc_cont=0.697
我现在想将文件名添加到标题中,因为我想注释每个文件的序列。我尝试了以下操作:
for file in *.faa;
do
sed -i "s/>.*/${file%%.*}/" "$file" ;
done
它部分工作,但它从标题中删除了“>”,这对于 fasta 文件至关重要。我尝试修改“${file%%.*}”部分以保留胡萝卜,但它总是让我指出错误的替换。
我也尝试过这个:
awk '/>/{sub(">","&"FILENAME"_");sub(/\.faa/,x)}1' *.faa
这在理论上是有效的,但只在我的终端上打印所有内容,而不是在相应的文件中更改它。
有人可以帮忙吗?
尚不清楚您是否要替换较早的标头,或添加到其中。这两种情况都很容易做到。不要替换您不想替换的文本。
for file in ./*.faa;
do
sed -i "s/^>.*/>${file%%.*}/" "$file"
done
将替换标题,但在替换中包含前导
>
,从而有效地保留它;和
for file in ./*.faa;
do
sed -i "s/^>.*/&${file%%.*}/" "$file"
done
将在标头末尾附加文件名(替换字符串中的
&
计算为我们要替换的字符串,再次有效地保留它)。
对于另一种变化,请尝试
for file in *.faa;
do
sed -i "/^>/s/\$/ ${file%%.*}/" "$file"
done
它表示在与正则表达式
^>
匹配的行上,将行 $
末尾的空字符串替换为文件名。
当然,您的 Awk 脚本也可以轻松修复。标准 Awk 没有选项来并行
-i
的“就地”选项 sed
,但您可以轻松使用临时文件:
for file in ./*.faa;
do
awk '/>/{ $0 = $0 " " FILENAME);sub(/\.faa/,"")}1' "$file" >"$file.tmp" &&
mv "$file.tmp" "$file"
done
GNU Awk 还有一个
-i inplace
扩展,如果您有 GNU Awk,您可以简单地将其添加到现有脚本的选项中。
由于 FASTA 文件通常包含多个标头,因此添加到标头而不是用相同的字符串替换文件中的所有标头似乎更有用,因此我更改了您的 Awk 脚本来执行此操作。
就其价值而言,角色
^
的名字是caret(胡萝卜是🥕)。字符 >
称为 大于 或 直尖括号、 或 右断 或有时只是 楔子。
您只需要检测要替换的模式并使用正则表达式来实现它:
fasta_helper.sh
location=$1
for file in $location/*.faa
do
full_filename=${file##*/}
filename="${full_filename%.*}"
#scape special chars
filename=$(echo $filename | sed 's_/_\\/_g')
echo "adding file name: $filename to: $full_filename"
sed -i -E "s/^[^#]+/>$filename /" $location/$full_filename
done
用途:
只需传递包含 fasta 文件的文件夹即可:
bash fasta_helper.sh /foo/bar
测试:
讲座
建议首先使用
find
命令或 ls
命令识别您的文件。
find . -type f -name "*.faa" -printf "%f\n"
find
命令仅打印文件扩展名为 .faa
的文件。包括当前目录的子目录。
ls -1 "*.faa"
用于打印扩展名为
ls
的文件和目录的 .faa
命令。在当前目录中。
获得正确的文件列表后,迭代该列表并应用
sed
命令。
for fileName in $(find . -type f -name "*.faa" -printf "%f\n"); do
stripedFileName=${fileName/.*/} # strip extension .faa
sed -i "1s|\$| $stripedFileName|" "fileName" # append value of stripedFileName at end of line 1
done