繁体   English   中英

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

[英]How do I remove part of a line in a multi-line chunk using sed or Perl?

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

@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中有一个紧凑的方法吗?

假设你只是不想盲目地删除以+开头的每一行的其余部分,那么你可以这样做:

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

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

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

如果你可以使用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行。

也许只是sed '/^@/+2 s/+.*/+/'

编辑 :这将无法正常工作,但作为vim命令,它应该工作:

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

这可能对你有用:

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

或者使用GNU sed:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM