【问题标题】:Remove every n lines for removing datablock using sed or awk使用 sed 或 awk 删除用于删除数据块的每 n 行
【发布时间】:2015-07-22 20:26:02
【问题描述】:

我有一个由 316125000 行组成的大文件。这个文件由112500个数据块组成,每个数据块有2810行。

我需要减小文件的大小,所以我想保留第 1、10、20、...第 112490 和第 112450 个数据块,并删除所有其他数据块。结果,这将给我 11250 个数据块。

这意味着我想删除每 2811 ~ 28100 行,每 1~2810 和 28101~30910 .... 行。

我在考虑 awk、sed 或 grep,但哪个更快,我该如何实现?我知道如何使用 awk 和 NR 删除每个第 2 或第 3 行,但我不知道如何重复删除大块行。

谢谢

最好的,

【问题讨论】:

  • 请注意,“1st, 10th, 20th...” 不是在序列开头的每 10 个:10-1 = 9, 20-10 = 10。每 10 个可以是第 10 个,第 20 个, 30th...(没有第 1 个),或 1st, 11th, 21st...(或等效地,从 0 编号时的块 0, 10, 20...)。在我的回答中,我假设您实际上是指后者以避免使第一个块成为特殊情况。
  • 是的,看来我在这里做错了。我也试图每 10 个获得一次,第一个成为特别的,你已经指出了。那个 awk 代码效果很好。

标签: bash awk sed grep


【解决方案1】:

类似的方法可能会起作用:

awk 'int((NR - 1) / 2810) % 10 == 0' <infile >outfile

也就是说,int((NR - 1) / 2810) 给出当前行 (NR) 的 2810 行块的(从零开始的)编号,如果该块编号除以 10 的余数为 0(% 10 == 0 ) 打印该行。这应该会导致每 10 个块被打印一次,包括第一个(块号 0)。

【讨论】:

    【解决方案2】:

    我猜不出哪个最快,但我可以为您的基准测试提供一个 GNU sed 配方:

    sed -e '2811~28100,+25289d' <input >output
    

    这表示:从第 2811 行开始,之后的每 28100 行,删除它和接下来的 25289 行。

    等效地,我们可以使用sed -n 并每 28100 行打印第 1-2810 行:

    sed -ne '1~28100,+2809p' <input >output
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 2023-03-05
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多