Мне нужно напечатать вторую строку для каждого запроса в другом файле

  1. В APUE говорится, что «FIFO могут использоваться для дублирования выходного потока», но не говорится, что FIFO фактически дублируют выходной поток. Как вы заметили, в примере дублирование выполняется с помощью tee.

  2. mkfifoсоздает FIFO, видимый как «файл» в содержащем каталоге; но запись в FIFO отличается от записи в файл, потому что данные никогда не попадают на диск. Каналы, названные или иные, не обеспечивают хранение данных, они обеспечивают каналы связи; записывающий конец канала не может записывать данные, если нет получателя, канал просто передает данные, не сохраняя их. (В большинстве систем каналы поддерживаются небольшими буферами ядра для повышения производительности, но это детали реализации.)

  3. Линейные соединения между процессами представляют собой конвейеры, которые можно представить в виде линейного графа. В примере вы можете представить последнюю строку как

    infile → prog1 → tee fifo1 → prog3
    

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

    infile → prog1 → prog2
                   → prog3
    

    который не является -линейным (в графе есть один узел, prog1который имеет два выходных узла ).

1
27.10.2019, 15:52
3 ответа
sed -E "/^$/d" file | awk '/> Query/{printf "%s\t", $3; nr[NR+2]}; NR in nr '

Выход

TRINITY_DN109574_c0_g1_i1       ***** No hits found *****
TRINITY_DN109587_c0_g1_i1       ***** No hits found *****
TRINITY_DN109586_c0_g2_i1       Sequences producing significant alignments:

Прохождение...

Ваш идентификатор и расстояние между строками совпадений различаются в зависимости от того, получили вы попадание или нет, но расстояние меняется только с дополнительной пустой строкой, поэтому, если мы удалим все пустые строки

sed -E "/^$/d" file 

то строка совпадения/не совпадения всегда находится на 2 строки впереди запроса. Затем мы передаем |это в awk, чтобы найти только те строки, которые являются началом запроса

awk '/> Query/'

но нам нужно только 3-е (разделенное пробелом )поле $3из строки запроса, потому что это ваш идентификатор

awk '/> Query/{print $3}'

Всякий раз, когда мы находим соответствие регулярному выражению, мы также хотим вычислить номер строки совпадающей строки Hits и сохранить его в массиве. Я назвал массив nr, а интересующая нас строка Hits — это текущая совпадающая строка NR+2

awk '/> Query/{print $3; nr[NR+2]}'

Наконец, добавьте второе условие, чтобы проверить, существует ли в нашем массиве nrстрока NR, которая не соответствует регулярному выражению, и распечатать ее. Также меняем первый printна printf, чтобы число попаданий выводилось в конце идентификатора.

awk '/> Query/{printf "%s\t", $3; nr[NR+2]}; NR in nr;'

Обратите внимание, что это решение не работает, если число, добавленное к NR, не соответствует следующему регулярному выражению.

2
27.01.2020, 23:30

Используя GNU sed, мы накапливаем строки в пространстве шаблонов, начиная со строки запроса, продолжаем отбрасывать пустые строки и печатаем, когда накапливаются 3 непустые строки.

$ sed -e '
    :loop
        /\n.*\n/{
            s//\t/
            s/^> Query=//p
         }
         /^> Query=/!d
         $d;N
         s/\n$//
     bloop
' file

В Perl мы глотаем файл и получаем строку запроса, пропускаем все пустые строки, пропускаем первую непустую строку

$ perl -0777ne 'print "$1\t$2" while /^> Query=\h+(.*)\n\n*.*\n\n*(.*\n)/mg' file
0
27.01.2020, 23:30

Используя GNU grep в режиме pcre, мы сначала извлекаем строку запроса, за которой следуют 2 непустые строки, промежуточные пустые строки могут варьироваться от нуля до нескольких.

$ < file grep -zoP '(?m:^> Query=\h+\K.*\n\n*(.*\n\n*){2})' |
    tr -d '\0' | tr -s '\n' |
    sed -e 'h;n;n;H;g;s/\n/\t/'

Другой метод с использованием оператора диапазона...:

$ perl -lane '
    $e = (/^> Query=/ && $c==0)... (/\S/ && $c==2);
    next if !length($e) || !@F;
    $q = $F[2]       if $e == 1;
    print "$q\t$_" if $e =~ /E0/;
    $c = $c == 2 ? 0 : $c+1;
  ' file 
0
27.01.2020, 23:30

Теги

Похожие вопросы