我希望从大型文本文件(~870,000,000行)中提取某些行组。例如,在50行文件中,我可能需要第3-6、18-27和39-45行。
通过浏览堆栈溢出,我发现bash命令:
tail -n+NUMstart file |head -nNUMend是获得一行或一组行的最快方法,从NUMstart开始,再到NUMend。然而,当读取多组行时,这似乎是效率低下的。通常情况下,这一技术并不那么重要,但是对于这么大的文件,它会产生巨大的影响。
有比对每组行使用上面的命令更好的方法吗?我假设答案很可能是bash命令,但实际上对任何语言/工具都是开放的,这些语言/工具将做得最好。
发布于 2017-01-03 20:35:07
awk去营救!
awk -v lines='3-6,18-27,39-45' '
BEGIN {n=split(lines,a,",");
for(i=1;i<=n;i++)
{split(a[i],t,"-");
rs[++c]=t[1]; re[c]=t[2]}}
{for(i=s;i<=c;i++)
if(NR>=rs[i] && NR<=re[i]) {print; next}
else if(NR>re[i]) s++;
if(s>c) exit}' file提供上次打印行之后的早期退出。没有错误检查,范围应按递增顺序提供。
发布于 2017-01-03 20:24:24
tail -n XX file | head -n YY针对不同范围的问题是,您要运行它几次,因此效率低下。否则,benchmarks认为它们是最好的解决方案。
对于这种特殊情况,您可能需要使用awk
awk '(NR>=start1 && NR<=end1) || (NR>=start2 && NR<=end2) || ...' file就你而言:
awk '(NR>=3 && NR<=6) || (NR>=18 && NR<=27) || (NR>=39 && NR<=45)' file也就是说,对范围进行分组,当它们发生时让awk打印相应的行,只需循环一次文件。添加最后一个NR==endX {exit} (endX是最后一个范围中的结束项)也是有用的,这样它就可以在读取最后一个有趣的行后完成处理。
就你而言:
awk '(NR>=3 && NR<=6) || (NR>=18 && NR<=27) || (NR>=39 && NR<=45); NR==45 {exit}' filehttps://stackoverflow.com/questions/41451662
复制相似问题