【问题标题】:How To Delete First X Lines Based On Minimum Lines In File如何根据文件中的最小行删除前 X 行
【发布时间】:2016-11-11 21:00:22
【问题描述】:

我有一个包含 10,000 行的文件。使用以下命令,我将删除第 10,000 行之后的所有行。

sed -i '10000,$ d' file.txt

但是,现在我想删除前 X 行,使文件不超过 10,000 行。

我想应该是这样的:

sed -i '1,$x d' file.txt

$x 是超过 10,000 行的行数。我有点纠结于如何写 if,然后是它的一部分。或者,我想我可以使用原始命令,然后只使用 cat 反向文件?

例如,如果我们只想要底部的 3 行(经过一些有用的答案后似乎更简单):

输入:

Example Line 1
Example Line 2
Example Line 3
Example Line 4
Example Line 5

预期输出:

Example Line 3
Example Line 4
Example Line 5

当然,如果您知道一种更有效的命令编写方式,我也会对此持开放态度。非常感谢您的积极投入。

【问题讨论】:

  • 啊,好的,我现在加一下哈哈。
  • 为什么一个简单的tail -n 3 file 不适合你?
  • 是的,@kaylum 提供了这一点。我选择了sed 选项,因为它已经到位并且已经是我正在努力解决的问题。
  • sed 用于在单个行上进行简单替换,仅此而已。不要仅仅因为它有一个 -i 选项告诉它动态创建一个临时文件而不是你必须命名它,就被引诱将它用于其他东西(例如删除文件的部分)。只需为每项作业使用正确的工具,如果您必须自己命名临时文件,与必须弄清楚每项作业要跳过哪些复杂的 sed 语法箍相比,这没什么大不了的。

标签: linux bash unix awk sed


【解决方案1】:

tail 可以做你想做的事。

tail -n 10000 file.txt

【讨论】:

    【解决方案2】:

    为简单起见,我将反转文件,保留前 10000 行,然后重新反转文件。

    这使得原地保存文件变得更加复杂

    source=file.txt
    temp=$(mktemp)
    tac "$source" | sed '10000 q' | tac > "$temp" && mv "$temp" "$source"
    

    无需反转文件,您将计算行数并进行一些算术运算:

    sed -i "1,$(( $(wc -l < file.txt) - 10000 )) d" file.txt
    

    【讨论】:

    • 为什么不直接tail
    • @hidefromkgb,如果你提供答案,我会投票给tail
    • 你用的是什么外壳? /bin/sh? echo "$(($(wc -l &lt; file.txt)-10000)) 的输出是什么?
    【解决方案3】:
    $ awk -v n=3 '{a[NR%n]=$0} END{for (i=NR+1;i<=(NR+n);i++) print a[i%n]}' file
    Example Line 3
    Example Line 4
    Example Line 5
    

    如果您有 GNU awk 并且想要进行“就地”编辑,请添加 -i inplace

    【讨论】:

    • 我明白这如何让您的生活更轻松。谢谢埃德。
    【解决方案4】:

    保留前 10000 行:

    head -n 10000 file.txt 
    

    保留最后 10000 行:

    tail -n 10000 file.txt
    

    使用您的文件示例进行测试

    tail -n 3 file.txt
    Example Line 3
    Example Line 4
    Example Line 5
    

    【讨论】:

      【解决方案5】:

      tac file.txt | sed "$x q" | tac | sponge file.txt

      sponge 命令在此处有助于避免额外的临时文件。

      【讨论】:

      • 如果您正在反转文件,那么您希望保留 first 10000 行。
      • 问题询问关于删除前 X 行以使生成的文件不超过 10,000 行。当x 为 10000 时,此命令将保留最后 9,999 行。
      • 假设你想保留最后 5 行。这样做可以吗?seq 20 | tac | sed '1,5d' | tac ?不,它删除最后 5 行。您需要在管道中使用 sed -n '1,5p'sed 5q
      • 但如上所述,tail 似乎是这里更好的选择。
      【解决方案6】:

      tail -10000 &lt;&lt;&lt;"$(cat file.txt)" &gt; file.txt

      好吧,不只是“只是”tail,但这样它就可以就地截断。

      【讨论】:

      • 喜欢就地使用。
      • 太丑了。但它有效。如果外壳支持,我会使用$(&lt; file.txt)。节省几微秒。
      • 你确定它有效吗?什么保证 shell 在执行 cat file.txt 之前不会执行 &gt; file.txt?没有什么可以说服我对任何重要数据执行该代码。
      • shell 保证 I/O 重定向是从左到右处理的。但是,here-strings 的实际工作方式非常模糊,我不会假设 cat 实际上必须在继续进行下一个重定向之前完成。
      • @chepner Here-strings 只是 here-documents 的一种变体,对吧?官方手册指出 «所有 读取到该点 [终止行] 的行然后 用作标准输入»(请参阅3.6.6 Here Documents)。
      猜你喜欢
      • 1970-01-01
      • 2010-12-03
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2019-07-07
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      相关资源
      最近更新 更多