sed:删除文件中除最后X行外的所有行


Answers:


9

基本上,您正在模仿尾巴。在此示例中X = 20。以下示例将删除除最后20行以外的所有内容:

sed -e :a -e '$q;N;21,$D;ba' filename

说明:

  • -e:a创建一个称为a的标签
  • 下一个-e:
    • $ q-如果它是最后一行,则退出并打印模式空间
    • N-下一行
    • 21,$ D-如果行号> = 21,则执行“ D”命令(21,$ =第21行到$,即文件的末尾)
    • ba-分支到标签“ a”,这是脚本的开始。

它可以用作尾巴,但是我无法使其就位(与原始问题中的一样)
Matteo 2012年

2
+1 ...顺便说一句。-i如果将两个-e表达式压缩为一个,则可以使用它。您也可以通过将bash变量传递$1给它来使用它... sed -i ':a;$q;N;'$(($1+1))',$D;ba' filename...但是要求0行数,将返回1行。
Peter.O 2012年

@ Peter.O这真让我震惊。您能解释一下'$(($1+1))'吗?
tjt263'6

6

sed当涉及到这样的任务时,它是非常复杂的。tailgrep否则awk会使此操作变得容易得多,应改为使用。话虽如此,这可能的。

以下解决方案适用于sed和多行搜索和替换

sed -ni '
    # if the first line copy the pattern to the hold buffer
    1h
    # if not the first line then append the pattern to the hold buffer
    1!H
    # if the last line then ...
    ${
            # copy from the hold to the pattern buffer
            g
            # delete current line if it is followed by at least X more lines
            # replace X-1 with the proper value
            s/.*\n\(\(.*\n\)\{X-1\}\)/\1/
            # print
            p
    }
' filename

如果没有评论,它就很漂亮。如果要消除(例如)除最后十行之外的所有内容,请使用以下命令:

sed -ni '1h;1!H;${;g;s/.*\n\(\(.*\n\)\{9\}\)/\1/;p;}' filename

在非GNU sed上,在-i之后需要-e。
Matteo 2012年

就像phiz的答案一样,这不会处理对0最后行的请求...但是,这就是建议使用其他工具的原因之一。
Peter.O 2012年

2

根据sed手册4.13节中的脚本,您可以执行以下操作:

n=10

(( n > 1 )) && script='1h; 2,'$n'{H;g;}; $q; 1,'$((n-1))'d; N; D'
(( n > 1 )) || script='$!d'

sed -i "$script" infile

0

TAC | sed的| TAC> &&(MV ||猫>)

以下两条命令片段都会有效删除的最后5行以外的所有内容~/file1。如果要保留最后10,则可以根据需要将替换|sed '1,5!d;'|sed '1,10!d;'等等

  1. tac ~/"file1" |sed '1,5!d;' |tac >"/tmp/file2" &&mv  "/tmp/file2"  ~/"file1"
  2. tac ~/"file1" |sed '1,5!d;' |tac >"/tmp/file2" &&cat "/tmp/file2" >~/"file1"
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.