如何避免sed中的最后一个换行符?

时间:2019-02-26 12:17:52

标签: sed

我要删除文件的最后部分,从某个模式之后的一行开始,并包括前面的换行符

因此,在“ STOP”处停止以下文件:

keep\n
STOP\n
whatever

应输出:

keep

没有尾随换行符。

我尝试了这个,逻辑似乎可行,但是似乎sed每次打印缓冲区时都会添加换行符。我该如何避免呢?当sed不能操纵缓冲区时,我没有那个问题(即,如果我删除STOP,sed会在文件末尾输出“ whatever”,而没有换行符)。

printf 'keep
STOP
Whatever' | sed 'N
/\nSTOP/ {
  s/\n.*$//
  P
  Q
}
P
D'

我正在尝试编写git cleaning过滤器,并且每次提交时都不能添加新的换行符。

3 个答案:

答案 0 :(得分:2)

这可能对您有用(GNU sed):

sed -z 's/\nSTOP.*//' file

-z选项将整个文件插入到内存中,并执行替代命令,从第一行(后跟STOP)中删除文件的其余部分。

答案 1 :(得分:2)

$ awk '/^STOP/{exit} {printf "%s%s", ors, $0; ors=RS}' file
keep$

上面的代码打印的每一行都没有尾随换行符,而是之前加上换行符(\n\r\n-取决于您的环境要求,以便在UNIX或Windows上正确运行Windows或其他))。找到停止线后,它将在打印任何内容之前退出。

请注意,上述内容除了当前行外不会在内存中保留任何内容,因此无论您的输入文件有多大,无论STOP出现在哪里,它都可以工作-如果STOP是文件的第一行与您到目前为止的其他答案不同。

它也可以在每个UNIX盒的任何shell中使用任何awk来工作。

答案 2 :(得分:1)

使用awk,您可以:

$ awk '$0=="STOP"{exit} {b=b (b==""?"":ORS) $0} END{printf "%s",b}' file

输出:

keep$

解释:

$ awk '                        
    $0=="STOP" { exit }        # exit at STOP, ie. go to END
    { b=b (b==""?"":ORS) $0 }  # gather an output buffer, control \n
    END { printf "%s",b }      # in the END output output buffer
' file    

...更多(重点介绍条件运算符):

    b=b             # appending to b, so b is b and ...
    (b==""?"":ORS)  # if b was empty, add nothing to it, if not add ORS ie. \n ...
    $0              # and the current record