我有一系列文件,看起来像这样,第二列和第三列是重复的,但有数千行。
AT1G15820.1 TRINITY_DN96909_c1_g2_i1.p1 TRINITY_DN96909_c1_g2_i1.p1 1.36e-115
AT1G15820.1 TRINITY_DN96909_c1_g1_i2.p1 TRINITY_DN96909_c1_g1_i2.p1 9.97e-113
AT1G15820.1 TRINITY_DN96909_c1_g1_i1.p1 TRINITY_DN96909_c1_g1_i1.p1 6.26e-66
我想截取第3列并截断它,以便删除字符串中在_I之后(包括_I(的所有内容,如下所示:
AT1G15820.1 TRINITY_DN96909_c1_g2_i1.p1 TRINITY_DN96909_c1_g2 1.36e-115
AT1G15820.1 TRINITY_DN96909_c1_g1_i2.p1 TRINITY_DN96909_c1_g1 9.97e-113
AT1G15820.1 TRINITY_DN96909_c1_g1_i1.p1 TRINITY_DN96909_c1_g1 6.26e-66
每个字母组合(DN、c、g、i、p(后面的数字可以是任何数字,也可以是任何长度,所以我不能只是截断到某个长度。
我尝试过sed -i 's/_i.*//' file.txt
,但这删除了每行之后的所有内容,而不仅仅是感兴趣的列。
非常感谢!
您可以使用awk:从第一次出现的_i
中删除,然后删除第三个字段中的行的其余部分
awk 'sub(/_i.*/, "", $3)1' file
输出
AT1G15820.1 TRINITY_DN96909_c1_g2_i1.p1 TRINITY_DN96909_c1_g2 1.36e-115
AT1G15820.1 TRINITY_DN96909_c1_g1_i2.p1 TRINITY_DN96909_c1_g1 9.97e-113
AT1G15820.1 TRINITY_DN96909_c1_g1_i1.p1 TRINITY_DN96909_c1_g1 6.26e-66
使用sed
$ sed -i.bak 's/(g[0-9]*)_[^ ]*/1/2' input_file
AT1G15820.1 TRINITY_DN96909_c1_g2_i1.p1 TRINITY_DN96909_c1_g2 1.36e-115
AT1G15820.1 TRINITY_DN96909_c1_g1_i2.p1 TRINITY_DN96909_c1_g1 9.97e-113
AT1G15820.1 TRINITY_DN96909_c1_g1_i1.p1 TRINITY_DN96909_c1_g1 6.26e-66
您可以在第二次出现匹配时执行替换
awk '{sub(/_[^_]+$/,"",$3)}1' file
AT1G15820.1 TRINITY_DN96909_c1_g2_i1.p1 TRINITY_DN96909_c1_g2 1.36e-115
AT1G15820.1 TRINITY_DN96909_c1_g1_i2.p1 TRINITY_DN96909_c1_g1 9.97e-113
AT1G15820.1 TRINITY_DN96909_c1_g1_i1.p1 TRINITY_DN96909_c1_g1 6.26e-66
在第三个字段中,删除最后一个下划线(包括(之后的所有内容。
这将使用GNU-sed:
sed 's/(.*_i.*)_i.*(s.*)/12/' your_file > output_file
(
和)
是捕获组,它们记住里面匹配的东西(.*_i.*)_i.*
记得直到(但不包括(第二个_i
的所有内容(s.*)
记住从第二个_i
之后的空间到行的末尾的所有内容- CCD_ 10用第一和第二捕获组替换该行(即,从第二CCD_
输出
AT1G15820.1 TRINITY_DN96909_c1_g2_i1.p1 TRINITY_DN96909_c1_g2 1.36e-115
AT1G15820.1 TRINITY_DN96909_c1_g1_i2.p1 TRINITY_DN96909_c1_g1 9.97e-113
AT1G15820.1 TRINITY_DN96909_c1_g1_i1.p1 TRINITY_DN96909_c1_g1 6.26e-66
一个perl单行:
perl -lane '$F[2] = join "_", (split /_/, $F[2])[0..3]; print "@F"' file
这将拆分下划线上的第三个字段,获取前4个组件并用下划线连接它们。