2017-02-16 63 views
0

我想根据行是否包含某些字符串将文件分成两个不同的文件。如果一行包含“ITS”,则该行和紧随其后的行将写入ITS.txt文件;如果一行包含“V34”,那么该行和该行之后将写入文件“V34.txt”。 我的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(您的代码在某些情况下会产生意外的输出),并查看代码中不必要的重复。现在添加一个调试'打印'打印每一行读 - 很难,对吧? –

相关问题