如何在 sed 中打印除倒数第 N 行以外的所有内容?

如何在 sed 中打印除倒数第 N 行以外的所有内容?
  • 我想做以下的补充/“相反”

    sed 13q;d <file.txt
    

    更一般地说,是否可以在 中进行这种补/逆/相反操作sed?或者仅适用于正则表达式?

  • 如何打印除倒数第三行以外的所有内容?这是否需要两位tac并向前计数sed?或者有没有办法让sed自己从后面数?

答案1

第1部分

只需d删除第13行:

sed '13d' <file.txt

补充上述内容的一般方法是:

sed '13!d' <file.txt

第2部分

因为它可以做到:

sed -n ':a;${P;q};N;4,$D;ba' <file.txt

请注意,该4数字比您需要的数字多 1。因此,如果您想要最后 10 行,则为11.

测试用seq

$ seq 100 | sed -n ':a;${P;q};N;4,$D;ba'
98
$ 

尝试解释

:a        # define label a
${        # match the last line
    P     # print the first line of the pattern space
    q     # quit
}
N         # match all lines: append the next line to the pattern
4,${      # match the range of lines 4 to the end of the file
    D     # delete the first line of the pattern space
}
ba        # match all lines: jump back to label a 

格伦·杰克曼的宝贵补充:

那是“只有第N行”。这是“除了第 N 行之外的所有行”:

sed -n ':a;${s/^[^\n]*\n//;p;q};N;4,${P;D};ba'

适用于 GNU sed,该\n序列可能不适用于其他 sed。


我用 BSD sed (OSX) 尝试了一下,发现它在上面的形式中不太有效。这些问题似乎是:

  1. ;用于分隔行似乎通常有效,但在标签之后不起作用
  2. BSD sed 似乎需要;在单行{}命令组中的最后一个命令之后,而 GNU sed 则不需要
  3. \n通常可以在正则表达式中使用,但显然不能在[]括号表达式中使用。因此,要排除换行符,我们可以使用类似的东西[[:alnum:][:punct:][:graph:][:blank:]],尽管这可能会排除其他字符(特别是其他控制字符)。

所以这是对更加独立于平台的版本的尝试:

sed -n ':a
${s/^[[:alnum:][:punct:][:graph:][:blank:]]*\n//p;q;};N;4,${P;D;};ba'

这似乎可以在 OSX 和 Ubuntu 下运行。

相关内容