2017-02-16 13 views
0

Я пытаюсь разделить файл на два разных файла на основе того, содержит ли строка определенную строку. Если строка содержит «ITS», эта строка и строка сразу после нее будут записываться в файл ITS.txt; если строка содержит «V34», то эта строка и строка сразу после нее будут записаны в файл «V34.txt». Мой AWK кодЕсть ли эффективный способ разделения строк на разные файлы, awk в этом случае?

awk '/ITS/{print>"ITX.txt";getline;print>"ITX.txt";}; /V34/{print>"V34.txt";getline;print>"V34.txt";}' seqs.fna 

Он хорошо работает. Но мне интересно, есть ли эффективный способ сделать это?

seqs.fna (9-10G)

>16S.V34.S7.5_1 
    ACGGGAGGCAGCAGTAGGGAATCTTCC 
    >PCR.ITS.S8.14_2 
    CATTTAGAGGAAGTAAAAGTCGTAACA 
    >PCR.ITS.S7.11_3 
    CATTTAGAGGAAGTACAAGTCGTAACAAGGTTTCCGTAGGTGAACCTGCGGAAGGATCATTTTTGAAGGCTACAC 
    >16S.V34.S8.6_4 
    ACGGGCGGCAGCAGTAGGGAAT 
    >16S.V34.S8.13_5 
    ACGGGCGGCAGCAGTAGGGAATCTTCCGCAATGGGCGAAAGCCTGACGGAGCAACGCCGCGTGAGTGATGAAGGTCTTCGGATCGTAAAACTCTGT 
    >16S.V34.S7.14_6 
    ACGGGGGGCAGCAGTAGGGAATCTTCCACAATGGGTGCAAACCTGATGGAGCAATGCCG 
    >16S.V34.S8.4_7 
    ACGGGAGGCAGCAGTAGGGAATCTTCCACAAT 
    >16S.V34.S8.14_8 
    CGTAGAGATGTGGAGGAACACCAGTGGCGAAG 
    >16S.V34.S8.8_9 
    CTGGGATAACACTGACGCTCATGCACGAAAGCGTGGGGAGCAAACAGGATTAGATACCCTTGTAGTC 
    >16S.V34.S7.3_10 
    GGTCTGTAATTGACGCTGAGGTTCGAAAGCGTGGGGAGCGAACAGGATTAGATACCCGGGTAGTC 

ответ

2

getline имеет несколько очень конкретных целей, и это не было бы один из них. См. http://awk.freeshell.org/AllAboutGetline. Если вы переписали сценарий без GetLine вы бы решить эту проблему самостоятельно, но с учетом входного файла размещены, это все, что вам нужно:

awk -F'.' '/^>/{out=$2".txt"} {print > out}' seqs.fna 

Чтобы узнать, как правильно использовать AWK, читать книгу Эффективное Awk Программирование, 4-е издание, автор Арнольд Роббинс.

+1

Благодарим вас за быстрый элегантный ответ. Работает отлично. – Bigyellowbee

+0

Как насчет этого. Кажется, это меньше времени, чем ваш метод в файле около 7G. 'awk '/ ITS/{getline X; print $ 0 RS x>" sl_out/2fungi.fna ";};/V34/{getline x; print $ 0 RS x> "sl_out/216s.fna";} './Sl_out/seqs.fna' – Bigyellowbee

+0

'Кажется, что используется меньше времени' - я сомневаюсь. Однако, если есть разница во времени, это будет несущественным/крошечным, но предоставит статистические данные 3-й итерации в вашем вопросе, если вы хотите обсудить. Awk не C. Как и любой другой инструмент/язык, вам нужно изучить парадигму, а не только синтаксис, использовать ее эффективно. Снова прочитайте http://awk.freeshell.org/AllAboutGetline, чтобы понять, когда/как использовать getline (в некоторых случаях ваш код будет выдавать неожиданный результат) и просто посмотрите на ненужное дублирование кода. Теперь добавьте отладку 'print' для печати каждой строки, прочитанной - так, правильно? –