linux 提取文件第n行,从文件中获取第n行的Bash工具

我有一个独特的情况,我可以基准的解决方案在这一页,所以我写这个答案,作为对建议的解决方案与每个包含的运行时间的整合。

设置

我有一个3.261 GB的ASCII文本文件,每一行只有一个键值对。该文件总共包含3,339,550,320行,并且无法在我尝试过的任何编辑器中打开,包括我的Go-to Vim。我需要对这个文件进行子集,以便研究我所发现的一些值,这些值仅从500,000,000行左右开始。

因为文件有这么多行:我只需要提取行的一个子集就可以对数据做任何有用的事情。

阅读每一行,直到我关心的值,将需要很长的时间。

如果解决方案读取了我关心的行,并继续读取文件的其余部分,那么它将浪费时间读取将近30亿个不相关的行,并且花费比需要长6倍的时间。

我最好的解决方案是只从文件中提取一行,而不读取文件中的任何其他行,但我想不出如何在Bash中实现这一点。

为了我的理智,我不会试图阅读我自己的问题所需要的全部5亿行。相反,我将尝试从3,339,550,320行中提取第50,000,000行(这意味着读取完整文件所需的时间将比需要长60倍)。

我将使用time内置以对每个命令进行基准测试。

基线

首先让我们看看head tail解决办法:$ time head -50000000 myfile.ascii | tail -1pgm_icnt = 0real    1m15.321s

第五千万行的基线是00:01:15.321,如果我直接用五亿行的话,大概是12.5分钟。

我对这件事很怀疑,但值得一试:$ time cut -f50000000 -d$'\n' myfile.ascii

pgm_icnt = 0real    5m12.156s

这一次花了00:05:12.156才运行,这比基线慢得多!我不确定它是读取了整个文件,还是在停止之前只读取了5000万行,但无论如何,这似乎并不是解决问题的可行方法。

AWK

我只使用exit因为我不打算等待完整的文件运行:$ time awk 'NR == 50000000 {print; exit}' myfile.ascii

pgm_icnt = 0real    1m16.583s

该代码在00:01:16.583中运行,这只比基线慢了1秒,但仍然没有对基线进行改进。按照这种速度,如果退出命令被排除在外,那么读取整个文件可能需要大约76分钟的时间!

Perl

我还运行了现有的Perl解决方案:$ time perl -wnl -e '$.== 50000000 && print && exit;' myfile.ascii

pgm_icnt = 0real    1m13.146s

该代码运行于00:01:13.146,比基线快了2秒。如果我用5亿英镑运行,大概要花12分钟。

SED

最重要的答案是,这是我的结果:$ time sed "50000000q;d" myfile.ascii

pgm_icnt = 0real    1m12.705s

该代码运行于00:01:12.705,比基线快3秒,比perl快0.4秒。如果我在完整的500,000,000行上运行它,可能需要12分钟。

地图档

我有bash3.1,因此不能测试mapfile解决方案。

结语

看起来,在大多数情况下,很难在head tail解决办法。充其量sed解决方案提高了大约3%的效率。

(按公式计算的百分比)% = (runtime/baseline - 1) * 100)

第50,000,000行00:01:12.705 (-00:00:02.616 = -3.47%) sed

00:01:13.146 (-00:00:02.175 = -2.89%) perl

00:01:15.321 (+00:00:00.000 = +0.00%) head|tail

00:01:16.583 (+00:00:01.262 = +1.68%) awk

00:05:12.156 (+00:03:56.835 = +314.43%) cut

第500,000,000行00:12:07.050 (-00:00:26.160) sed

00:12:11.460 (-00:00:21.750) perl

00:12:33.210 (+00:00:00.000) head|tail

00:12:45.830 (+00:00:12.620) awk

00:52:01.560 (+00:40:31.650) cut

第3,338,559,320行01:20:54.599 (-00:03:05.327) sed

01:21:24.045 (-00:02:25.227) perl

01:23:49.273 (+00:00:00.000) head|tail

01:25:13.548 (+00:02:35.735) awk

05:47:23.026 (+04:24:26.246) cut

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值