awk в заявлении while

У меня есть следующий ввод:

cat moldata >species_1 ?????????CACTTGGArGGTGGAGCCAAGAAGGTTATTATTTCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTC TGTCAACCTCGATTCTTATGACCCATCTGCTAAGGTCATTTCGAATGCTTCCTGCACCACCAACTGCCTCGCTCCCCT >species_2 CCAAGGTCATCCATGACAACTTTGAGATCATTGAAGGCCTGATGACCACTGTACACGCCACCACCGCTACTCAGAAGA GTCGACGGACCTTCCGGTAAACTCTGGCGTGATGGTCGTGGCGCTCAACAAAACATCATTCCCGCCTCTACTGGTGCT >species_3 CAAAGCCGTAGGCAAAGTCATTCCTGCTCTCAACGGTAAACTGACTGGCATGGCCTTCCGTGTTCCCGTTCCAAATGT CGGTTGTGGATCTTACTGTTCGCyTGGGAAAACCAGCCTCTTATGACrCCATTAAACAGAAGGTCAAGGAGGCTGCTG >species_4 GGTCCTTTGAAGGGTATTCTTGGATACACCGAAGATCAAGTTGTGTCCACCGACTTTGTTGGAGACACACACTCTTCA CTTTGACGCTGCTGCTGGTATCTCCCTCAACGATAACTTCGTCAAACTTATCAGCTGGTACGACAATGAATATGGATA >species_5 GTTCCGCAAAGCTCAATGCCCTATTGTTGAGCGTCTGACCAATTCTCTCATGATGCATGGCCGCAACAACGGCAAGAA TGATGGCAGTGCGAATTGTTAAGCATGCCTTTGAAATCATCCACCTTCTGACTGGAGAGAATCCTCTTCAAGTACTCG 

и я хотел бы получить от moldata запись вида (название вида + блок строк, следующих за ним до следующей записи вида) для перечисленных здесь видов:

 cat species_list species_1 species_3 species_5 

для получения следующего результата:

 cat output >species_1 ?????????CACTTGGArGGTGGAGCCAAGAAGGTTATTATTTCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTC TGTCAACCTCGATTCTTATGACCCATCTGCTAAGGTCATTTCGAATGCTTCCTGCACCACCAACTGCCTCGCTCCCCT >species_3 CAAAGCCGTAGGCAAAGTCATTCCTGCTCTCAACGGTAAACTGACTGGCATGGCCTTCCGTGTTCCCGTTCCAAATGT CGGTTGTGGATCTTACTGTTCGCyTGGGAAAACCAGCCTCTTATGACrCCATTAAACAGAAGGTCAAGGAGGCTGCTG >species_5 GTTCCGCAAAGCTCAATGCCCTATTGTTGAGCGTCTGACCAATTCTCTCATGATGCATGGCCGCAACAACGGCAAGAA TGATGGCAGTGCGAATTGTTAAGCATGCCTTTGAAATCATCCACCTTCTGACTGGAGAGAATCCTCTTCAAGTACTCG 

Я пытался заставить awk работать в цикле while:

 while read line; do if grep -q "$line" moldata; then echo $line | awk -v line=${line} 'BEGIN {RS=">"} /line/ {print $0}' moldata >> output; else echo "$line not found"; fi; done < species_list 

Я читал о опции getline с awk но я не мог заставить ее работать.

5 Solutions collect form web for “awk в заявлении while”

Если вы настаиваете на том, чтобы сделать это с awk :

 ( echo -n '/^>('; paste -sd\| - <species_list | tr -d '\n'; echo -n ')/,/^$/' ) | \ awk -f - moldata 

Для одиночной записи вы можете сделать что-то вроде этого:

 awk '/species_1/{print;while (getline line){if(line !~/species/) print line; else break} }' input.txt >species_1 ?????????CACTTGGArGGTGGAGCCAAGAAGGTTATTATTTCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTC TGTCAACCTCGATTCTTATGACCCATCTGCTAAGGTCATTTCGAATGCTTCCTGCACCACCAACTGCCTCGCTCCCCT 

С помощью нескольких элементов вам может понадобиться следующее:

 $ while IFS= read -r line > do > awk -v spec="$line" '$0~spec{print;while (getline line){if(line !~/species/) print line; else break} }' input.txt > done < species.txt >species_1 ?????????CACTTGGArGGTGGAGCCAAGAAGGTTATTATTTCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTC TGTCAACCTCGATTCTTATGACCCATCTGCTAAGGTCATTTCGAATGCTTCCTGCACCACCAACTGCCTCGCTCCCCT >species_3 CAAAGCCGTAGGCAAAGTCATTCCTGCTCTCAACGGTAAACTGACTGGCATGGCCTTCCGTGTTCCCGTTCCAAATGT CGGTTGTGGATCTTACTGTTCGCyTGGGAAAACCAGCCTCTTATGACrCCATTAAACAGAAGGTCAAGGAGGCTGCTG >species_5 GTTCCGCAAAGCTCAATGCCCTATTGTTGAGCGTCTGACCAATTCTCTCATGATGCATGGCCGCAACAACGGCAAGAA TGATGGCAGTGCGAATTGTTAAGCATGCCTTTGAAATCATCCACCTTCTGACTGGAGAGAATCCTCTTCAAGTACTCG 

Альтернативное решение с использованием двух файлов в качестве аргументов

Зная, что данные в примере OP всегда есть две строки после имени вида, мы можем загружать имена видов в species.txt в массив, а затем использовать для цикла, чтобы прочитать строку дважды и распечатать ее.

 $ awk 'FNR==NR{species[$0]}; NR!=FNR{ sub(/>/,"");if ($0 in species){ print $0; for(i=0;i<=1;i++) {getline data;print data} }}' species.txt input.txt species_1 ?????????CACTTGGArGGTGGAGCCAAGAAGGTTATTATTTCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTC TGTCAACCTCGATTCTTATGACCCATCTGCTAAGGTCATTTCGAATGCTTCCTGCACCACCAACTGCCTCGCTCCCCT species_3 CAAAGCCGTAGGCAAAGTCATTCCTGCTCTCAACGGTAAACTGACTGGCATGGCCTTCCGTGTTCCCGTTCCAAATGT CGGTTGTGGATCTTACTGTTCGCyTGGGAAAACCAGCCTCTTATGACrCCATTAAACAGAAGGTCAAGGAGGCTGCTG species_5 GTTCCGCAAAGCTCAATGCCCTATTGTTGAGCGTCTGACCAATTCTCTCATGATGCATGGCCGCAACAACGGCAAGAA TGATGGCAGTGCGAATTGTTAAGCATGCCTTTGAAATCATCCACCTTCTGACTGGAGAGAATCCTCTTCAAGTACTCG 
 declare -a list readarray list < /path/to/species_list for species in ${list[@]}; do sed -ne "/$species/,/^\$/p" moldata done 

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

«При специальном распределении пустая строка в качестве значения RS указывает, что записи разделены одной или несколькими пустыми строками», поэтому

 awk ' BEGIN { OFS=FS="\n"; RS=""; ORS="\n\n" } FNR==NR { for (k=0;k<NF;) ++species[">"$++k] } $1 in species ' species_list moldata 
 $ awk ' NR==FNR{ sp[$0]; next } # this is for reading species data into sp array /species/ { # from this point for moldata's lines if (substr($0,2) in sp) { # if the read line match with data in sp array print # first print title while(getline > 0) { # and then read until blank line and print if (NF == 0) { print ""; break } print } } } ' species_list moldata >species_1 ?????????CACTTGGArGGTGGAGCCAAGAAGGTTATTATTTCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTC TGTCAACCTCGATTCTTATGACCCATCTGCTAAGGTCATTTCGAATGCTTCCTGCACCACCAACTGCCTCGCTCCCCT >species_3 CAAAGCCGTAGGCAAAGTCATTCCTGCTCTCAACGGTAAACTGACTGGCATGGCCTTCCGTGTTCCCGTTCCAAATGT CGGTTGTGGATCTTACTGTTCGCyTGGGAAAACCAGCCTCTTATGACrCCATTAAACAGAAGGTCAAGGAGGCTGCTG >species_5 GTTCCGCAAAGCTCAATGCCCTATTGTTGAGCGTCTGACCAATTCTCTCATGATGCATGGCCGCAACAACGGCAAGAA TGATGGCAGTGCGAATTGTTAAGCATGCCTTTGAAATCATCCACCTTCTGACTGGAGAGAATCCTCTTCAAGTACTCG 
  • Извлечь определенный текст из переменной в сценарии оболочки
  • Как сообщить «sed» на месте изменения
  • sed one-liner для удаления любой строки, начинающейся с цифры
  • Как разобрать скрипт на Bash? (платформа MIPS)?
  • Замена строки в файле
  • Как заменить путь в файле новым путем с помощью sed?
  • Параллелизация sed дает разную производительность
  • Как заставить sed выполнять действия только в первом матче?
  • Извлечение строк, содержащих PAT1, но не PAT2 с sed
  • Заменить маркер в текстовом файле произвольным новым текстом
  • Проблема с передачей переменной sed
  • Linux и Unix - лучшая ОС в мире.