我正在尝试更改以>
开始的行中的长名称,以便我只保留部分直到Stage_V_sporulation_protein...
:
>tr_A0A024P1W8_A0A024P1W8_9BACI_Stage_V_sporulation_protein_AE_OS=Halobacillus_karajensis_OX=195088_GN=BN983_00096_PE=4_SV=1
MTFLWAFLVGGGICVIGQILLDVFKLTPAHVMSSFVVAGAVLDAFDLYDNLIRFAGGGATVPITSFGHSLLHGAMEQADEHGVIGVAIGIFELTSAGIASAILFGFIVAVIFKPKG
>tr_A0A060LWV2_A0A060LWV2_9BACI_SpoIVAD_sporulation_protein_AEB_OS=Alkalihalobacillus_lehensis_G1_OX=1246626_GN=BleG1_2089_PE=4_SV=1
MIFLWAFLVGGVICVIGQLLMDVVKLTPAHTMSTLVVSGAVLAGFGLYEPLVDFAGAGATVPITSFGNSLVQGAMEEANQVGLIGIITGIFEITSAGISAAIIFGFIAALIFKPKG
我正在做一个循环:
cat file.txt | while read line; do
if [[ $line = >* ]] ; then
cut -d_ -f1-4 $line;
fi;
done
但是在地址文件中,而不是在文件中的行(我得到cut: >>tr_A0A024P1W8_A0A024P1W8_9BACI_Stage_V_sporulation_protein_AE_OS=Halobacillus_karajensis_OX=195088_GN=BN983_00096_PE=4_SV=1: No such file or directory
)。
我想要的输出是:
>tr_A0A024P1W8_A0A024P1W8_9BACI
MTFLWAFLVGGGICVIGQILLDVFKLTPAHVMSSFVVAGAVLDAFDLYDNLIRFAGGGATVPITSFGHSLLHGAMEQADEHGVIGVAIGIFELTSAGIASAILFGFIVAVIFKPKG
>tr_A0A060LWV2_A0A060LWV2_9BACI
MIFLWAFLVGGVICVIGQLLMDVVKLTPAHTMSTLVVSGAVLAGFGLYEPLVDFAGAGATVPITSFGNSLVQGAMEEANQVGLIGIITGIFEITSAGISAAIIFGFIAALIFKPKG
如何更改实际行?
在问题的当前状态下,似乎最容易做到的是:
awk '/^>/ {print $1,$2,$3,$4; next}1' FS=_ OFS=_ file.txt
行开头匹配>
的行只打印前四个字段,用_
(OFS
的值)分隔。不匹配的行将原样打印。
使用sed:
sed -E '/^>/s/(.*)_Stage_V_sporulation_protein/1/' file
sed
的一行代码是:
sed '/^>/s/^(([^_]*_){3}[^_]*).*/1/' file
使用下面的Perl一行代码处理FASTA文件中的头文件:
perl -lpe 'if ( m{^>} ) { @f = split m{_}, $_; splice @f, 4; $_ = join "_", @f; }' file.txt > out.txt
Perl单行程序使用这些命令行标志:-e
:告诉Perl查找内联代码,而不是在文件中查找。-p
:每次循环输入一行,默认赋值给$_
。在每次循环迭代后添加print $_
。-l
:在执行内联代码之前去掉输入行分隔符(*NIX默认为"n"
),并在打印时附加。
一行代码使用split
将下划线上的输入字符串拆分为数组@f
.
然后使用splice
从数组中删除除前4个元素外的所有元素。
最后,join
用下划线连接这些元素。
以上所有内容都被包装在if ( m{^>} ) { ... }
中,以便将昂贵的字符串操作限制在FASTA头(以>
开头的行)。
参见:perldoc perlrun
:如何执行Perl解释器:命令行切换