如何使用sed或Perl删除多行块中的部分行?

时间:2011-01-27 06:21:58

标签: linux perl unix sed

我有一些看起来像这样的数据。它有四个块。每个块都以@字符开头。

@SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
AAAAAAAAAAAAAAAAAAAAAAAAAAA
+SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
::::::::::::::::::::::::;;8
@SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
888888888888888888888888888

在每个块的第三行,我想删除+字符后面的文本,结果是:

@SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
AAAAAAAAAAAAAAAAAAAAAAAAAAA
+
::::::::::::::::::::::::;;8
@SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+
888888888888888888888888888

在sed或Perl中有一种紧凑的方法吗?

5 个答案:

答案 0 :(得分:4)

假设您不想盲目删除以+开头的每个行的其余部分,那么您可以这样做:

sed '/^@/{N;N;s/\n+.*/\n+/}' infile

输出

$ sed '/^@/{N;N;s/\n+.*/\n+/}' infile
@SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
AAAAAAAAAAAAAAAAAAAAAAAAAAA
+
::::::::::::::::::::::::;;8
@SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+
888888888888888888888888888
+Dont remove me

*注意:虽然@上的上述命令键可以确定是否应更改带有+的行,但 仍会改变第二行恰好也是以+开头。这听起来不是这种情况,但如果你想排除这个角落的情况,下面的小改动也可以防止这种情况发生:

sed '/^@/{N;N;s/\(.*\)\n+.*/\1\n+/}' infile

输出

$ sed '/^@/{N;N;s/\(.*\)\n+.*/\1\n+/}' ./infile
@SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
+AAAAAAAAAAAAAAAAAAAAAAAAAAA
+
::::::::::::::::::::::::;;8
@SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+
888888888888888888888888888
+Dont remove me

答案 1 :(得分:3)

如果第一行或第二行永远不会有+,而第三行总是一行:

perl -0100pi -e's/\+.*/+/' datafile

否则:

perl -0100pi -e's/^((?:.*\n){2}.*?\+).*/$1/' datafile

或在5.10 +:

perl -0100pi -e's/^(?:.*\n){2}.*?\+\K.*//' datafile

所有那些假设@只出现在一个块的开头。如果它可能出现在其他地方,那么:

perl -pi -e's/\+.*/+/ if $. % 4 == 3' datafile

答案 2 :(得分:1)

如果你可以使用awk,你可以这样做:

 gawk '{if ($0 ~ /^@/ ) { print ; getline ; print ; getline ; print "+"}}' INPUTFILE

因此,如果gawk在行的开头看到@,它将被打印出来,然后下一行将被淹没&&打印,最后啜饮第3行(@之后),并仅打印+

如果+不在行的开头,则可以使用gensub(/\+.*/,"+",$0)代替上一个"+"中的print

(如果你安装了perl,很可能会有一个a2p可执行文件,可以将上面的awk脚本转换为perl,如果你想... ...

HTH

更新(缺少第4行):

 gawk '{if ($0 ~ /^@/ ) { print ; getline ; print ; getline ; print "+"; getline; print }}' INPUTFILE

这也应该打印第4行。

答案 3 :(得分:0)

可能只是sed '/^@/+2 s/+.*/+/'

编辑:这不起作用,但作为vim命令,它应该有效:

vim file -c ':g/^@/+2s/+.*/+/' -c 'wq'

答案 4 :(得分:0)

这可能对您有用:

sed '/^@/{$!N;$!N;$!N;s/\n+[^\n]*/\n+/g}' file

或使用GNU sed:

sed '/^@/,+3s/^+.*/+/' file