如何打印sed中除第N行之外的所有内容?


9
  • 我想做的补充/“相反”

    sed 13q;d <file.txt
    

    更一般而言,是否可以在中进行这种补/逆/对sed?还是仅用于正则表达式?

  • 我如何打印除倒数第二行外的所有行?这是否需要2 tac并向前计数sed?还是有办法让sed自己从背后开始计数?

Answers:


12

第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该数字比您所需的数字大一。因此,如果您想要最后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 

格伦·杰克曼(Glenn Jackman)的宝贵补充:

那是“仅第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下使用。


@jimmij关于SE网络中相关问题的其他答案表明head/ tail解决方案比sed解决方案要慢得多。不过谢谢
同构2014年

3
@isomorphismes没有程序可以知道文件中的行数,除非它遍历整个文件。没有办法解决。从底部开始计数的唯一方法是反转文件并从顶部开始计数或将其解析两次。所以头/尾巴将尽可能快。
terdon

@isomorphismes ...因为它们(head/ tail)已针对其工作进行了优化。
彼得2014年

@isomorphismes-编辑了您需要的所有部分
Digital Trauma

真好!我不得不更改答案,因为我以某种方式期望它会更复杂。:)
彼得
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.