我要删除文件的最后部分,从某个模式之后的一行开始,并包括前面的换行符。
因此,在“ 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过滤器,并且每次提交时都不能添加新的换行符。
答案 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