【问题标题】:How can I delete every Xth line in a text file?如何删除文本文件中的每 N 行?
【发布时间】:2012-04-11 07:20:36
【问题描述】:

考虑一个包含科学数据的文本文件,例如:

5.787037037037037063e-02 2.048402977658663748e-01
1.157407407407407413e-01 4.021264347118673754e-01
1.736111111111111049e-01 5.782032163406526371e-01

如何轻松删除文件中的每两行或每 10 行中的每 9 行?例如,是否可以使用 bash 脚本?

背景:文件非常大,但我需要的数据要少得多。请注意,我使用的是 Ubuntu/Linux。

【问题讨论】:

  • 您确定要像这样对数据进行点采样吗?进行下采样可能会更好,其中来自 N 行组的数据以某种适当的方式进行平均。点采样可能会导致混叠问题。

标签: bash text


【解决方案1】:

尝试类似:

awk 'NR%3==0{print $0}' file

这将打印三分之一的行。或者:

awk 'NR%10<9{print $0}' file 

将打印十行中的九行。

【讨论】:

  • 打印是默认操作,所以不需要print $0
  • 我知道。不过对我来说太奇怪了。 (我不是经验丰富的 awk 用户。)
  • @123: 但可能是 9。
  • @Mat Yep 误读了,因为您输入了will print 9 lines out of ten.,所以我认为意图是每十行打印一次(我认为您已经完成了 NR%10 的冗余版本),而它实际上删除了每 10 行中的第 9 行。
【解决方案2】:

你可以用 sed 来做,例如

sed -n -e 'p;N;d;' file # print every other line, starting with line 1

如果你有 GNU sed 这很容易

sed -n -e '0~10p' file # print every 10th line
sed -n -e '1~2p' file # print every other line starting with line 1
sed -n -e '0~2p' file # print every other line starting with line 2

【讨论】:

    【解决方案3】:

    这很容易用 awk 完成。

    删除每隔一行:

    awk 'NR % 2 == 0' file > newfile
    

    每 10 行删除一次:

    awk 'NR % 10 != 0' file > newfile
    

    awk 中的 NR 变量是行号。 awk 中 { } 之外的任何内容都是条件,默认操作是打印。

    【讨论】:

    • 以前从未听说过 awk。现在肯定会检查出来!谢谢!
    • Awk 非常适合在 shell 脚本中处理文本。它还可以做浮点数学,这是 bash 做不到的。绝对值得为 shell 编码人员花时间学习。
    • 第一个命令会留下带有偶数 id 的行,它不会删除它。如果要删除它,请使用 awk 'NR % 2 != 0' file > newfile。
    • 删除列怎么样?
    • 第一个可以重写为!(NR % 2),第二个可以重写为NR % 10
    【解决方案4】:

    您可以使用 awk 和 shell 脚本。 awk 可能很困难,但是......

    这将删除你告诉它的特定行:

    nawk -f awkfile.awk [filename]
    
    awkfile.awk contents
    
    BEGIN {
    if (!lines) lines="3 4 7 8"
    n=split(lines, lA, FS)
    for(i=1;i<=n;i++)
     linesA[lA[i]]
    }
    !(FNR in linesA)
    

    我也不记得 VIM 是否带有标准的 Ubuntu。如果没有得到它。

    然后用vim打开文件 vim [文件名]

    然后输入

    :%!awk NR\%2 or :%!awk NR\%2 
    

    这将删除每隔一行。只需将 2 更改为不同频率的另一个整数。

    【讨论】:

      【解决方案5】:

      perl 怎么样?

      perl -n -e '$.%10==0&&print'       # print every 10th line
      

      【讨论】:

      • 他想删除每 10 行,而不是保留每 10 行。轻松更改您的代码,!= 而不是 ==。
      • 没有。他说“我怎样才能轻松地删除,例如,每隔一行,或每 10 行中的 9 行?”,每 10 行中删除 9 行?表示每 10 次打印一次。正如你所说,一旦发布了解决方案,它就很容易适应,所以我没有费心去纠正犯同样错误的其他发帖者。
      • 再次阅读问题后,我相信您的解释是正确的。
      • 是的;删除每 10 行不会大大减少要绘制的数据。目的似乎是对一些大型数据集进行点采样。
      【解决方案6】:

      这可能对你有用(GNU sed):

      seq 10 | sed '0~2d' # delete every 2nd line
      1
      3
      5
      7
      9
      seq 100 | sed '0~10!d' # delete 9 out of 10 lines
      10
      20
      30
      40
      50
      60
      70
      80
      90
      100
      

      【讨论】:

        猜你喜欢
        • 2019-05-31
        • 1970-01-01
        • 1970-01-01
        • 2022-10-01
        • 2022-01-27
        • 1970-01-01
        • 2019-10-06
        • 2011-07-28
        • 2021-06-20
        相关资源
        最近更新 更多