【问题标题】:Print a file, skipping the first X lines, in Bash [duplicate]在 Bash 中打印文件,跳过前 X 行 [重复]
【发布时间】:2010-10-10 22:20:14
【问题描述】:

我有一个很长的文件要打印,例如跳过前 1,000,000 行。

我查看了 cat 手册页,但没有看到任何选项。我正在寻找执行此操作的命令或简单的 Bash 程序。

【问题讨论】:

    标签: linux bash printing skip


    【解决方案1】:

    我发现删除文件前十行的最简单方法:

    $ sed 1,10d file.txt
    

    X 是要删除的初始行数的一般情况下,请将此归功于评论者和编辑:

    $ sed 1,Xd file.txt
    

    【讨论】:

    • 在更一般的情况下,您必须使用sed 1,Xd,其中 X 是要删除的初始行数,X 大于 1。
    • 如果您不知道文件有多长并且不想告诉 tail 打印最后 100000000 行,这更有意义。
    • @springloaded 如果你需要知道文件的行数,'wc -l' 很容易给你
    【解决方案2】:

    用途:

    sed -n '1d;p'
    

    此命令将删除第一行并打印其余部分。

    【讨论】:

    • 比 tail imo 好,因为我们不必知道要被尾化的行数。我们只删除第一行,仅此而已
    • @Tom 你不需要知道尾数,跳过第一行使用tail +2
    • 确实不错
    【解决方案3】:

    使用sed delete commandrange address。例如:

    sed 1,100d file.txt # Print file.txt omitting lines 1-100.
    

    或者,如果您只想打印已知范围,请使用带有-n 标志的打印命令:

    sed -n 201,300p file.txt # Print lines 201-300 from file.txt
    

    无论是否存在 GNU 实用程序,此解决方案都应该在所有 Unix 系统上可靠运行。

    【讨论】:

    • 对 cli 和脚本最容易使用的答案。
    【解决方案4】:

    如果你想跳过前两行:

    tail -n +3 <filename>
    

    如果你想跳过第一行:

    tail -n +$((x+1)) <filename>
    

    【讨论】:

    • 这有点误导,因为有人可能会按字面意思解释(x+1)。例如,对于 x=2,他们可以输入(2+1) 甚至(3),这两种方法都不起作用。更好的写法可能是:跳过前 X 行,Y=X+1,使用tail -n +Y &lt;filename&gt;
    【解决方案5】:

    如果您想查看前 10 行,可以使用 sed,如下所示:

    sed -n '1,10 p' myFile.txt
    

    或者,如果您想查看第 20 到 30 行,您可以使用:

    sed -n '20,30 p' myFile.txt
    

    【讨论】:

      【解决方案6】:

      你需要尾巴。一些例子:

      $ tail great-big-file.log
      < Last 10 lines of great-big-file.log >
      

      如果您确实需要跳过特定数量的“第一”行,请使用

      $ tail -n +<N+1> <filename>
      < filename, excluding first N lines. >
      

      也就是说,如果你想跳过 N 行,你开始打印第 N+1 行。示例:

      $ tail -n +11 /tmp/myfile
      < /tmp/myfile, starting at line 11, or skipping the first 10 lines. >
      

      如果您只想查看最后这么多行,请省略“+”:

      $ tail -n <N> <filename>
      < last N lines of file. >
      

      【讨论】:

      • 或 "tail --lines=+ ..." 用于可读命令人群:-)
      • 在 centos 5.6 中 tail -n +1 显示整个文件,tail -n +2 跳过第一行。奇怪的。 tail -c +&lt;num&gt; 也是如此。
      • @JoelClark 不,@NickSoft 是对的。在 Ubuntu 上,它是 tail -n +&lt;start number&gt;,我刚刚测试了它。所以tail -n +1 不会跳过任何内容,而是从第一行开始。
      • 我可以确认 tail -n +2 在 Darwin/Mac OS X 上也需要跳过第一行。
      • 这必须是过时的,但是,tail -n+2 OR tail -n +2 有效,就像所有使用 getopt 的短命令一样,您可以在它的开关旁边运行参数,前提是switch 是组中的最后一个,显然 tail -nv+2 之类的命令不起作用,它必须是 tail -vn+2。如果你不相信我自己试试。
      【解决方案7】:

      如果您的系统上有可用的 GNU tail,您可以执行以下操作:

      tail -n +1000001 huge-file.log
      

      + 字符可以满足您的需求。引用手册页:

      如果 K 的第一个字符(字节数或行数)是 `+',从每个文件开头的第 K 项开始打印。

      因此,如注释中所述,将 +1000001 与前 1,000,000 行之后的第一项开始打印。

      【讨论】:

      • 也适用于 BSD tail (OS X)
      • @Lloeki 太棒了! BSD head 不像 GNU 那样支持负数,所以我假设 tail 不接受正数(带 +),因为那是相反的。无论如何,谢谢。
      • 另外,为了澄清这个答案:tail -n +2 huge-file.log 会跳过第一行,然后在第 2 行接听。所以要跳过第一行,请使用 +2。 @saipraneeth 的回答很好地解释了这一点。
      【解决方案8】:

      带有 AWK 的不那么冗长的版本:

      awk 'NR > 1e6' myfile.txt
      

      但我建议使用整数。

      【讨论】:

      • 如果您需要跳过文件中间的某些行,则很有用,例如,awk '!(5 &lt; NR &amp;&amp; NR &lt; 10)'
      • 此版本适用于 Windows 版 Git 随附的 Cygwin 工具,而 tailsed 则不适用。例如,git -c color.status=always status -sb | awk 'NR &gt; 1' 给出了一个很好的最小状态报告,没有任何分支信息,当你的 shell 已经在提示中显示了分支信息时,这很有用。我将该命令分配给别名gs,这真的很容易输入。
      【解决方案9】:
      cat < File > | awk '{if(NR > 6) print $0}'
      

      【讨论】:

      • 这是 bash 中的语法错误——它在什么 shell 中起作用?
      • 我在 bash 中运行它。 不是命令的一部分,文件名应替换“”
      • awk 'NR &gt; 6 {print}' 就足够了...不需要 if 或 $0。
      • 实际上 awk 'NR&gt;6' 就足够了,因为 print 是默认的操作块 :-) 请参阅 linuxhandbook.com/awk-command-tutorial 以获得很好的 awk 教程,它很好地解释了这一点。
      【解决方案10】:

      只是提出一个sed 替代方案。 :) 要跳过前一百万行,请尝试 |sed '1,1000000d'

      例子:

      $ perl -wle 'print for (1..1_000_005)'|sed '1,1000000d'
      1000001
      1000002
      1000003
      1000004
      1000005
      

      【讨论】:

      • @Marlon,抱歉,这是错误的。这只适用于1d。例如,如果你在 2d 上使用它,你只会删除第 2 行。它不会删除行的范围。
      • @A-B-B 抱歉,意思是说这是迄今为止最简单的解决方案,这就是为什么我 +1 它没有试图纠正作者。
      【解决方案11】:

      我需要做同样的事情并找到了这个帖子。

      我尝试了“tail -n +,但它只是打印了所有内容。

      更多 + 行在提示符下运行良好,但在无头模式 (cronjob) 下运行时表现完全不同。

      我终于自己写了这个:

      skip=5
      FILE="/tmp/filetoprint"
      tail -n$((`cat "${FILE}" | wc -l` - skip)) "${FILE}"
      

      【讨论】:

      • Useless Use of Cat Award 的正确链接。前一个被广告取代。
      • @kub1x 我不认为这里的“cat”没有用,因为“cat | wc -l”产生的输出与简单的“wc -l”不同。前者适合算术运算,后者不适合。
      • @Jack 我没有判断cat 的使用,而只是修复了评论中的链接,导致页面失效。原来的评论一定已经被删除了。无论如何,感谢您指出这一点。
      • @kub1x 你知道吗?现在阅读链接后,我认为这里使用“cat”是错误的 :) 它应该类似于“wc -l
      【解决方案12】:

      这个 shell 脚本对我来说很好用:

      #!/bin/bash
      awk -v initial_line=$1 -v end_line=$2 '{
          if (NR >= initial_line && NR <= end_line) 
          print $0
      }' $3
      

      与此示例文件 (file.txt) 一起使用:

      one
      two
      three
      four
      five
      six
      

      命令(从文件的第二行到第四行提取):

      edu@debian5:~$./script.sh 2 4 file.txt
      

      此命令的输出:

      two
      three
      four
      

      当然,您可以改进它,例如通过测试所有参数值是否符合预期:-)

      【讨论】:

      • ++ 用于使用 awk,它比 tail 更便携
      【解决方案13】:

      您可以使用 head 和 tail 命令执行此操作:

      head -n <num> | tail -n <lines to print>
      

      其中 num 是 1e6 + 要打印的行数。

      【讨论】:

      • 不是最有效的答案,因为您需要在文件上执行“wc -l”以获得行数,然后添加百万:-)。你可以只用“尾巴”来做到这一点。
      • 我不确定,我的理解是在调用时会知道 1e6。不过倒数并不是最快的。
      猜你喜欢
      • 2017-01-18
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2016-05-21
      • 2021-02-17
      • 1970-01-01
      • 2017-01-28
      • 1970-01-01
      相关资源
      最近更新 更多