Как мне удалить часть строки в многострочном чанке, используя sed или Perl? - PullRequest
4 голосов
/ 27 января 2011

У меня есть некоторые данные, которые выглядят так. Он состоит из четырех частей. Каждый блок начинается с символа @.

@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 ]

4 голосов
/ 27 января 2011

Если вы просто не хотите слепо удалять остаток каждой строки, начинающейся с +, то вы можете сделать это:

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

* Примечание. Хотя приведенные выше командные клавиши на @ для определения необходимости изменения строки с +, будут по-прежнему изменять 2-ю строку, если это произойдеттакже начните с +.Не похоже, что это так, но если вы хотите исключить и этот угловой случай, от этого защитит следующее незначительное изменение:

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
3 голосов
/ 27 января 2011

Если в первой или второй строках никогда не будет +, а в третьей - всегда:

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
1 голос
/ 27 января 2011

Если вы можете использовать awk, вы можете сделать:

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

Таким образом, если gawk увидит @ в начале строки, он будет напечатан, тогда следующая строка будет распечатана и && напечатана, и, наконец, 3-я строка (после @) и только печать +.

Если + находится не в начале строки, вы можете использовать gensub(/\+.*/,"+",$0) вместо "+" в последнем print.

(И если у вас установлен perl, скорее всего, будет исполняемый файл a2p, который может преобразовать приведенный выше скрипт awk в perl, если вы хотите ...)

НТН

ОБНОВЛЕНИЕ (на пропущенной 4-й строке):

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

Также должна быть напечатана 4-я строка.

0 голосов
/ 18 марта 2012

Это может работать для вас:

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

или с GNU sed:

sed '/^@/,+3s/^+.*/+/' file
0 голосов
/ 27 января 2011

может быть просто sed '/^@/+2 s/+.*/+/'

edit : это не будет работать, но как команда vim должно работать:

vim file -c ':g/^@/+2s/+.*/+/' -c 'wq'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...