ror*_*oro 4 parallel-processing awk grep xargs
我有以下(大)文件,其中包含 30233088 个字符串:
head mystringfile.txt:
GAATGAACACGAAGAA
GAATGAACACGAAGAC
GAATGAACACGAAGAG
GAATGAACACGAAGCA
Run Code Online (Sandbox Code Playgroud)
cat sequence.txt
AAATAGAGGGCGGTCCAGGCGTGTCGAAACACTGGGTCCAGGGCAAGAGCGGTTCGGGTGTCAGGAAAGCCCCCAAGGGGGTTCGCGCGGTTTGCAGTGAGGTAGAGGCCGGTGTATGGGTAGACAATTGGGGTCCCAAAGAAAAAGGCTCGTCCAACATCATAATAAACCCAAGCACGATAAAAAGCAAACGCAGACTTCAATAGGGTACGAGCAATTGTGGCAGGGTGCTCGCTGTCAGGGTTAGATCTTCTTGGAGTCGCGTCGCTCGGGGGGGCAAGGCCAACGTAAGATCGTGGCTGATCGCTGGCAATGCGGTCGGTTGGGTGGTCGCTAGTAGGGGCACGGCGGTCTCTTATGGCGTCGTAAAATGCGTCTCCAAAGCGAAAAGGGGCGGCAGACAAGTCACCGGGCAAGCTTAGAGGTCTGGGGCCCGTGGCTTTAGGGGAATGAACACGAAGACGCGAAACGAAGTCGTGTTTCTTGTTGGCTGTAGAGGGGAAAACCGTCTGGGGCGATCTGGCGTAGTAGTGCGTGTCTTGCAGTGAGCTCCCCGTCCGTAAGGATTCGCAGGAATCCTGCGTGAAGCTCGGTCGTCTCGGCCGTGTCTCGGGGTTTGATTGCGGGTTCAGATTGGAAAGGTCTCCTCGGGTCGTTTGCTGCATTTGCTCGCAACCCTGACGTGAAAGGGGTGAGCTGTCTCCAATCTGCCACGCTGGGTGTTGCGTCGTCAGTAAAAGACTTGGTCAAGCTGGGACCTCGCAAGATCGCGAGAGGGTTAAGCACAAAAGGTATGGCGAAGCTCCCGGGTGCTCTTGTGGCCACCCAGAATCATGGTGACGTAGGTTTTGCGAAGCCATCAAAAATTCAGGCGGCAAAACGAGCCAGTAGGGTCCTGGGCAGCTGGGCTTGTAGTGGGTAGGCGGCAAAACGCAAAGAATGAACACGAAGCAACTCCGTAGTGTGACGGGGGTTCTGACAAACGTCCTGCAAGAAGTTCGTCTTGGG
Run Code Online (Sandbox Code Playgroud)
我需要grep在另一个序列文件中确定匹配的位置,我执行以下操作:
while read line; do grep -b -o $line sequence.txt >>sequence.txt.count; done<mystringfile.txt
Run Code Online (Sandbox Code Playgroud)
像这样运行代码当然需要很长时间并且只运行 1 个线程的一部分,那么我如何修改它(使用parallel或xargs?),以便它在我想要指定的尽可能多的线程上运行?
你的想法是错误的使用 shell 循环来处理文本。您正在打开一个新的文件描述符,以便为输入文件的 30233088 次迭代中的每一个重新定向到输出文件。它很容易产生巨大的性能影响或用完打开的文件描述符的情况。
为工作使用正确的工具。Awk是你的朋友吗?如果sequence.txt正如您所说的那样只是一个巨大的模式,您可以将它放入一个变量中以进行正则表达式匹配,如下所示。该解决方案不涉及必须在 RAM 中存储条目的内存开销
awk -v sequence="$(<sequence.txt)" 'n=index(sequence, $1){print n":"$1}' mystringfile.txt
Run Code Online (Sandbox Code Playgroud)
这应该比您采用的方法相对更快,并进一步加快速度,更改您的locale设置以匹配C本地,
LC_ALL=C awk -v sequence="$(<sequence.txt)" 'n=index(sequence, $1){print n":"$1}' mystringfile.txt
Run Code Online (Sandbox Code Playgroud)
要与打印字节偏移量开始的grep's 选项匹配,请在上面的答案中-b使用n-1而不仅仅是n.
如果您仍想使用 GNU 并行,请使用--pipepart将文件物理拆分为多个部分,并指定--block要读取的文件内容 MB的大小
parallel -a mystringfile.txt --pipepart --block=20M -q awk -v sequence="$(<sequence.txt)" 'n=index(sequence, $1){print n":"$1}'
Run Code Online (Sandbox Code Playgroud)