Извлечение K-й строки из кусков с помощью Sed / AWK / Perl - PullRequest
1 голос
/ 28 февраля 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
88888888888888888888888888

Что я хочу сделать, это извлечь последнюю строку каждого куска. Уступая:

::::::::::::::::::::::::;;8
888888888888888888888888888

Обратите внимание, что последняя строка фрагмента может содержать любой стандартный символ ASCII в том числе @.

Есть ли эффективный однострочник для этого?

Ответы [ 7 ]

4 голосов
/ 28 февраля 2011

Если нет пустых строк:

perl -ne 'print if $. % 4 == 0' file
4 голосов
/ 28 февраля 2011

Следующая команда sed выведет 3-ю строку после шаблона:

sed -n '/^@/{n;n;n;p}' file.txt
1 голос
/ 28 февраля 2011

Это работает так же, как и ответ собачьей рейки

awk '/^@/ {mark = NR} NR == mark + 3 {print}' inputfile

И, как и этот ответ, будет работать независимо от количества строк в каждом чанке (до тех пор, пока их не менее 4).

Прямой аналог этого ответа, однако, будет:

awk '/^@/ {next; next; next; print}' inputfile
1 голос
/ 28 февраля 2011

Печатает строки перед строками, которые начинаются с @, а также последнюю строку.Он может работать с чанками неоднородного размера, но предполагает, что только начальная строка чанка начинается с @.

sed -ne '1d;$p;/^@/!{x;d};/^@/{x;p}' file

Некоторое объяснение в порядке:

  • Сначала вы неВам не нужна первая строка, поэтому удалите ее 1d
  • Далее вам всегда нужна последняя строка, поэтому напечатайте ее $p
  • Если у вас нет совпадений, вставьте ее вудерживайте буфер и удалите его x;d
  • Если у вас есть совпадение, выньте его из буфера хранения и распечатайте его x;p
1 голос
/ 28 февраля 2011
$ awk 'BEGIN{RS="@";FS="\n"}{print $4 } ' file

::::::::::::::::::::::::;;8
88888888888888888888888888

Если у вас всегда есть эти 4 строки в чанке, некоторые другие способы

$ ruby -ne 'print if $.%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888

$ awk 'NR%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888

Также кажется, что ваша строка всегда идет после строки, начинающейся с "+", поэтому

$ awk '/^\+/{getline;print}' file
::::::::::::::::::::::::;;8
88888888888888888888888888

$ ruby -ne 'gets && print if /^\+/' file
::::::::::::::::::::::::;;8
88888888888888888888888888
0 голосов
/ 18 марта 2012

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

sed '/^@/,+2d' file
0 голосов
/ 02 марта 2011

это можно сделать с помощью grep легко

grep -A 1 '^@' ./infile
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...