【问题标题】:Efficient way to get n middle lines from a very big file从一个非常大的文件中获取 n 个中间行的有效方法
【发布时间】:2023-03-25 09:53:02
【问题描述】:

我有一个大约 60GB 的大文件。

我需要获取文件的 n 个中间行。 我正在使用带有头尾的命令,例如

tail -m file |head -n >output.txt
where m,n are numbers

文件的一般结构如下所示,带有一组记录(逗号分隔的列)。每行可以有不同的长度(比如最多 5000 个字符)。

col1,col2,col3,col4...col10

有没有其他方法可以让我用更少的时间完成 n 条中间行,因为当前命令需要大量时间来执行?

【问题讨论】:

  • 您能告诉我们更多关于您文件中的数据的信息,例如文件的一般结构吗?线是怎么分开的?每行的最大尺寸?以便我们可以尝试直接将内存遍历到所需的行?如果您的行的长度不相等,我们将不得不逐个字符地解析它。在这种情况下,您已经在使用最好的方法。
  • 将记录的一般结构添加到问题中。

标签: unix head tail


【解决方案1】:

使用 sed,您至少可以删除管道:

sed -n '600000,700000p' file > output.txt

将打印第 600000 到 700000 行。

【讨论】:

  • 如果有很多行最后一个请求的行之后,添加一个'q'命令可能会有所帮助:sed -n '600000,700000p;700000q' file。否则,sed 将继续运行,直到文件的最后一行被读取(即使没有打印任何内容)。
【解决方案2】:

awk 'FNR>=n && FNR

后跟文件名。

【讨论】:

    【解决方案3】:

    使用split 实用程序可能更有效,因为在管道中使用tailhead 会扫描文件的某些部分两次。

    示例

    split -l <k> <file> <prefix>
    

    其中k 是您希望在每个文件中包含的行数,并且(可选)prefix 被添加到每个输出文件名中。

    【讨论】:

    • 是的,我想过使用这个命令,但是我的机器没有太多空间来存储拆分的文件:(
    【解决方案4】:

    我能想到的加快搜索速度的唯一可能解决方案是构建和索引您的行,例如:

     0 00000000
     1 00000013
     2 00000045
       ...
     N 48579344
    

    然后,知道索引长度,您可以在数据文件的中间快速跳转(或任何您喜欢的地方......)。当然你应该在文件更改时保持索引更新......

    显然,此类问题的规范解决方案是将数据保存在数据库中(例如,参见 SQLite),而不是保存在普通文件中...:-)

    【讨论】:

    • 我的目的是将这些数据移动到数据库中。由于很少有记录的结构不正确,并且由于其他一些问题,我将它们分块移动到数据库中。
    【解决方案5】:

    以二进制随机存取方式打开文件,寻找中间,依次前进直到到达\n或\n\r ascii,从后面的字符转储N行开始到你的rest文件(一个\n -一条线)。任务完成。

    如果您的文件已排序,并且您需要两个键之间的数据,则使用上述方法 + 二分法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 2018-12-16
      • 1970-01-01
      • 2014-11-07
      • 1970-01-01
      • 2010-10-17
      相关资源
      最近更新 更多