3

我有一个大文件(1Gb),我需要使用记录号提取其中的几行。我用 sed 编写了我的脚本,但由于花费了太多时间,我决定对其进行调查。事实证明,当我运行类似 sed -n '15689,15696p' filename 之类的东西时,打印速度很快,但之后我有一个时间延迟,这让我的脚本变得非常慢。用 awk 做同样的任务,延迟更小,但它仍然存在!我用于 awk 的命令行是: awk 'NR>=15689 && NR<=15696' filename

我试图只打印一行(sed -n '15689p' 文件名)并且出现了同样的问题!

我想知道是否没有人以前见过这种情况并且知道如何摆脱这种愚蠢的延迟。在我看来这是一个大问题,因为这个延迟发生在打印任务之后!我已经在此论坛和其他论坛中进行了搜索,但没有看到有关此问题的问题。有人能帮我吗?谢谢

4

2 回答 2

3

这是因为它会扫描到文件的末尾。打印后试试这个退出:

sed -ne '15690q;15689p' file

或者使用 awk:

awk 'NR>=15689 && NR<=15696{print} NR==15697{exit}' filename

只是为了好玩,我运行了@RichardHum 的时间,而我的时间在带有 SSD 驱动器的 OSX Mavericks 上完全相反:

#!/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 解决方案,以防第一次缓存没有好处,但它肯定慢了几英里!

于 2014-05-27T14:12:21.063 回答
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
于 2014-05-27T14:14:50.737 回答