使用 unix(awk、sed、bash?)通过第 4 个下划线截断列中的项目?

Using unix (awk, sed, bash?) to truncate items in a column by the 4th underscore?

我有一系列看起来像这样的文件,第二列和第三列是重复的,但有数千行。

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 之后的所有内容,如下所示:

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但是这删除了每一行之后的所有内容,而不仅仅是感兴趣的列。

非常感谢!

使用sed

$ sed -i.bak 's/\(g[0-9]*\)_[^ ]*//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

您可以在第二次匹配时进行替换

这将使用 GNU sed 来完成:

sed 's/\(.*_i.*\)_i.*\(\s.*\)//' your_file > output_file
  • \(\)是捕获组,记住里面匹配的东西
  • \(.*_i.*\)_i.* 记住直到(但不包括)第二个 _i
  • 的所有内容
  • \(\s.*\) 记住从第二个 _i 之后的 space 到行尾
  • 的所有内容
  • // 用第一个和第二个捕获组替换该行(即删除从第二个 _i 到第一个 space 的所有内容。

产出

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(/_[^_]+$/,"",)}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

在第 3 个字段中删除最后一个下划线(包括)之后的所有内容。

您可以使用 awk 从第一次出现的 _i 中删除,然后是第三个字段中的其余行:

awk 'sub(/_i.*/, "", )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

一个 perl 单行代码:

perl -lane '$F[2] = join "_", (split /_/, $F[2])[0..3]; print "@F"' file

用下划线拆分第 3 个字段,获取前 4 个组件并用下划线连接它们。