我有一个大文件(1Gb),我需要使用记录号提取几行。我用sed写了我的脚本,因为花了太多时间,我决定调查它。 事实证明,当我运行类似的东西时 sed -n'15689,15696p'文件名 打印很快,但我有一段时间延迟,这使我的脚本变得非常慢。使用awk执行相同的任务延迟较小,但它仍然存在!我用于awk的命令行是: awk'NR> = 15689&& NR< = 15696'文件名
我尝试打印一行(sed -n'15689p'文件名),同样的问题就出现了!
我想知道以前是否有人见过这个,并知道如何摆脱这种愚蠢的延迟。在我看来这是一个大问题,因为这种延迟发生在打印任务之后!我已经在这个和其他论坛中搜索过,我没有看到这个问题的问题。 有人能帮我吗? 感谢
答案 0 :(得分:3)
避免使用sed -n '15689,15696p'
,因为sed会遍历整个文件。我知道的最快方式是:
head -15696 filename | tail -10
我对它进行了基准测试,并且运行得更快:
$ seq 1 100000000 > file
$ time (head -50000000 file | tail -10) > /dev/null
real 0m0.694s
user 0m0.830s
sys 0m0.333s
$ time (sed -n '49999991,50000000p' file) > /dev/null
real 0m6.018s
user 0m5.863s
sys 0m0.160s
$ time (sed -n '50000000q;49999991,50000000p' file) > /dev/null
real 0m3.197s
user 0m3.153s
sys 0m0.043s
$ time (awk 'NR>=49999991 && NR<=50000000' file) > /dev/null
real 0m12.665s
user 0m12.543s
sys 0m0.123s
$ time (awk 'NR>=49999991 && NR<=50000000{print} NR==50000001{exit}' file)
real 0m9.104s
user 0m9.010s
sys 0m0.100s
答案 1 :(得分:2)
因为它会直接扫描到文件的末尾。打印后尝试退出:
sed -ne '15690q;15689p' file
或者使用awk:
awk 'NR>=15689 && NR<=15696{print} NR==15697{exit}' filename
只是为了踢,我跑了@RichardHum的时间,我的OSX Mavericks完全与SSD驱动器相反:
#!/bin/bash -xv
seq 1 100000000 > file
time (head -50000000 file | tail -10) > /dev/null
time (sed -n '50000000q;49999991,50000000p' file) > /dev/null
time (awk 'NR>=49999991 && NR<=50000000{print} NR==50000001{exit}' file)
time (head -50000000 file | tail -10) > /dev/null
我得到了:
time (head -50000000 file | tail -10) > /dev/null
real 0m29.565s
user 0m35.711s
sys 0m0.733s
time (sed -n '50000000q;49999991,50000000p' file) > /dev/null
real 0m13.313s
user 0m13.162s
sys 0m0.150s
time (awk 'NR>=49999991 && NR<=50000000{print} NR==50000001{exit}' file)
real 0m7.433s
user 0m7.293s
sys 0m0.139s
time (head -50000000 file | tail -10) > /dev/null
real 0m29.560s
user 0m35.697s
sys 0m0.742s
我甚至在最后运行了head + tail解决方案,以防它第一次没有缓存的好处,但它肯定要慢一点!