使用 awk、sed 或其他方法从大量文件中打印行的有效方法?

duk*_*vin 5 performance sed awk

如果我有一个包含 800 万行的纯文本文件,并且我想将 4,000,010 到 4,000,000 行打印到屏幕上,哪个会更有效率:awk 还是 sed?

文本没有模式,不幸的是,数据库不是一种选择。我知道这并不理想,我只是想知道哪个能更快地完成任务。

或者也许有更好的替代 sed 或 awk 的方法?

ter*_*don 15

两者都不是,使用tailhead代替:

$ time tail -n 4000001 foo | head -n 11
real    0m0.039s
user    0m0.032s
sys     0m0.004s

$ time head -n 4000010 foo | tail -n 11
real    0m0.055s
user    0m0.064s
sys     0m0.036s
Run Code Online (Sandbox Code Playgroud)

tail实际上始终更快。我运行了这两个命令 100 次并计算了它们的平均值:

尾巴:

real    0.03962
user    0.02956
sys     0.01456
Run Code Online (Sandbox Code Playgroud)

头:

real    0.06284
user    0.07356
sys     0.07244
Run Code Online (Sandbox Code Playgroud)

我想tail更快,因为虽然它必须一直寻找到第 4e10 行,但在到达那里之前它实际上不会打印任何内容,而head将打印所有内容,直到第 4e10 + 10 行。


与按时间顺序排序的其他一些方法进行比较:

sed:

$ time sed -n 4000000,4000011p;q foo
real    0m0.312s
user    0m0.236s
sys     0m0.072s
Run Code Online (Sandbox Code Playgroud)

珀尔:

$ time perl -ne 'next if $.<4000000; print; exit if $.>=4000010' foo 
real    0m1.000s
user    0m0.936s
sys     0m0.064s
Run Code Online (Sandbox Code Playgroud)

awk:

$ time awk '(NR>=4000000 && NR<=4000010){print} (NR==4000010){exit}' foo 
real    0m0.955s
user    0m0.868s
sys     0m0.080s
Run Code Online (Sandbox Code Playgroud)

基本上,规则是你解析的越少,你的速度就越快。将输入视为只需要打印到屏幕上的数据流(同样tail如此)将始终是最快的方式。

  • 反过来做有什么缺点吗?我的意思是:`head -n 4000010 foo.txt | 尾-n 10`?这对我来说似乎是更直观的方法,因为它不需要您知道文件的确切长度。它甚至应该更快,因为 AFAIK `tail` 必须读取 *整个* 文件(为了知道有多少行),而 `head` 在适当的行数后停止读取。 (3认同)