Как извлечь несколько битов информации, которые отображаются на разных строках в одном текстовом файле

Я пытаюсь извлечь идентификатор последовательности и номер кластера, которые встречаются на разных строках одного и того же текстового файла.

Вход выглядит как

>Cluster 72 0 319aa, >O311_01007... * >Cluster 73 0 318aa, >1494_00753... * 1 318aa, >1621_00002... at 99.69% 2 318aa, >1622_00575... at 99.37% 3 318aa, >1633_00422... at 99.37% 4 318aa, >O136_00307... at 99.69% >Cluster 74 0 318aa, >O139_01028... * 1 318aa, >O142_00961... at 99.69% >Cluster 75 0 318aa, >O300_00856... *

. Желаемый вывод идентификатор последовательности в одном столбце и номер соответствующего кластера во втором.

>O311_01007 72 >1494_00753 73 >1621_00002 73 >1622_00575 73 >1633_00422 73 >O136_00307 73 >O139_01028 74 >O142_00961 74 >O300_00856 75

Может ли кто-нибудь помочь с этим?

8
задан 26 March 2018 в 09:02

8 ответов

Вот альтернатива Ruby как однострочный:

ruby -ne 'case $_; when /^>Cluster (\d+)/;id = $1;when /, (>\w{4}_\w{5})\.\.\./;puts "#{$1} #{id}";end' input_file

или разброс по нескольким строкам:

ruby -ne 'case $_ when /^>Cluster (\d+)/ id = $1 when /, (>\w{4}_\w{5})\.\.\./ puts "#{$1} #{id}" end' input_file

Я думаю, что это только более читаемо, чем awk, если вы знаете Ruby и regexen. В качестве бонуса этот код может быть немного более надежным, чем просто разделение строк, потому что он ищет окружающий текст.

3
ответ дан 17 July 2018 в 18:05

С awk:

awk -F '[. ]*' 'NF == 2 {id = $2; next} {print $3, id}' input-file мы разделяем поля на пространства или периоды с -F '[. ]*' с линиями из двух полей (строки >Cluster), сохраняем второе поле как идентификатор и перемещаем на следующую строку с другими строками, напечатайте третье поле и сохраненный идентификатор
13
ответ дан 17 July 2018 в 18:05

Вы можете использовать awk для этого:

awk '/>Cluster/{ c=$2; next }{ print substr($3,2,length($3)-4), c }' file

Первый оператор блока записывает идентификатор кластера. Оператор второго блока (по умолчанию) извлекает нужные данные и печатает его.

5
ответ дан 17 July 2018 в 18:05

Perl:

$ perl -ne 'if(/^>.*?(\d+)/){$n=$1;}else{ s/.*(>[^.]+).*/$1 $n/; print}' file >O311_01007 72 >1494_00753 73 >1621_00002 73 >1622_00575 73 >1633_00422 73 >O136_00307 73 >O139_01028 74 >O142_00961 74 >O300_00856 75

Объяснение

perl -ne: прочитайте файл ввода строки за строкой (-n) и примените сценарий, заданный -e, каждому линия. if(/^>.*?(\d+)/){$n=$1;}: если эта строка начинается с >, найдите самый длинный участок чисел в конце строки и сохраните это как $n. else{ s/.*(>[^.]+).*/$1 $n/; print: если строка не начинается с >, замените все на самое длинное растяжение символов не ., следующих за > (>[^.]+), то есть имя последовательности ($1, потому что мы захватили регулярное выражение) и текущее значение $n.

Или для более awk-подобного подхода:

$ perl -lane 'if($#F==1){$n=$F[1]}else{$F[2]=~s/\.+$//; print "$F[2] $n"}' file >O311_01007 72 >1494_00753 73 >1621_00002 73 >1622_00575 73 >1633_00422 73 >O136_00307 73 >O139_01028 74 >O142_00961 74 >O300_00856 75

Это всего лишь несколько более громоздкий способ сделать ту же основную идею, что и различные awk подходы. Я включаю его ради завершения и для поклонников Perl. Если вам нужно объяснение, просто используйте awk-решения:).

1
ответ дан 17 July 2018 в 18:05

Вот альтернатива Ruby как однострочный:

ruby -ne 'case $_; when /^>Cluster (\d+)/;id = $1;when /, (>\w{4}_\w{5})\.\.\./;puts "#{$1} #{id}";end' input_file

или разброс по нескольким строкам:

ruby -ne 'case $_ when /^>Cluster (\d+)/ id = $1 when /, (>\w{4}_\w{5})\.\.\./ puts "#{$1} #{id}" end' input_file

Я думаю, что это только более читаемо, чем awk, если вы знаете Ruby и regexen. В качестве бонуса этот код может быть немного более надежным, чем просто разделение строк, потому что он ищет окружающий текст.

3
ответ дан 23 July 2018 в 18:55

С awk:

awk -F '[. ]*' 'NF == 2 {id = $2; next} {print $3, id}' input-file мы разделяем поля на пространства или периоды с -F '[. ]*' с линиями из двух полей (строки >Cluster), сохраняем второе поле как идентификатор и перемещаем на следующую строку с другими строками, напечатайте третье поле и сохраненный идентификатор
13
ответ дан 23 July 2018 в 18:55
  • 1
    Вместо того, чтобы отбирать количество полей, лучше было бы явно искать $1 == ">Cluster" вместо NF == 2, в зависимости от того, что еще может быть в файле. – Monty Harder 26 March 2018 в 19:29

Вы можете использовать awk для этого:

awk '/>Cluster/{ c=$2; next }{ print substr($3,2,length($3)-4), c }' file

Первый оператор блока записывает идентификатор кластера. Оператор второго блока (по умолчанию) извлекает нужные данные и печатает его.

5
ответ дан 23 July 2018 в 18:55
  • 1
    Вам не нужно указывать " " как аргумент print. Просто используйте запятую для разделения аргументов, и она будет использовать OFS, пространство по умолчанию, чтобы отделить аргументы. – muru 26 March 2018 в 09:17
  • 2
    @muru правильный. спасибо – oliv 26 March 2018 в 09:18

Perl:

$ perl -ne 'if(/^>.*?(\d+)/){$n=$1;}else{ s/.*(>[^.]+).*/$1 $n/; print}' file >O311_01007 72 >1494_00753 73 >1621_00002 73 >1622_00575 73 >1633_00422 73 >O136_00307 73 >O139_01028 74 >O142_00961 74 >O300_00856 75

Объяснение

perl -ne: прочитайте файл ввода строки за строкой (-n) и примените сценарий, заданный -e, каждому линия. if(/^>.*?(\d+)/){$n=$1;}: если эта строка начинается с >, найдите самый длинный участок чисел в конце строки и сохраните это как $n. else{ s/.*(>[^.]+).*/$1 $n/; print: если строка не начинается с >, замените все на самое длинное растяжение символов не ., следующих за > (>[^.]+), то есть имя последовательности ($1, потому что мы захватили регулярное выражение) и текущее значение $n.

Или для более awk-подобного подхода:

$ perl -lane 'if($#F==1){$n=$F[1]}else{$F[2]=~s/\.+$//; print "$F[2] $n"}' file >O311_01007 72 >1494_00753 73 >1621_00002 73 >1622_00575 73 >1633_00422 73 >O136_00307 73 >O139_01028 74 >O142_00961 74 >O300_00856 75

Это всего лишь несколько более громоздкий способ сделать ту же основную идею, что и различные awk подходы. Я включаю его ради завершения и для поклонников Perl. Если вам нужно объяснение, просто используйте awk-решения:).

1
ответ дан 23 July 2018 в 18:55

Другие вопросы по тегам:

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