如何使用 sed 或 awk 等“有条件地”删除换行符?

Mtl*_*Dev 2 sed awk text-processing

给定一个包含多行的文件,其中一些=在最后。

我希望加入以下一行结尾的每一=行。任何其他换行符都应保持不变。

我一直无法做到这一点,因为sed似乎是逐行操作的,因此总是“添加”一个换行符。

示例输入:

Apple
Banana milkshake
Cherry =
Pie
Run Code Online (Sandbox Code Playgroud)

应该变成:

Apple
Banana milkshake
Cherry Pie
Run Code Online (Sandbox Code Playgroud)

我完全愿意使用sed/以外的工具awk

tha*_*isp 8

使用awk

$ awk '{ORS = sub(/=$/,"") ? "" : "\n"} 1' file
Apple
Banana milkshake
Cherry Pie
Run Code Online (Sandbox Code Playgroud)

使用条件表达式,我们将ORS(输出记录分隔符,默认值:换行符)设置为空字符串或换行符。sub()当在行尾完成替换时为真,删除现有的=,否则为假。在第一种情况下,我们设置ORS"",否则为"\n"1表示打印该行(使用ORS为每一行选择的值)。


或者,我们可以使用 GNUsed和零分离,假设文件对于内存来说不够大和小:

sed -z 's/=\n//g' file
Run Code Online (Sandbox Code Playgroud)

sed将整个文件作为一行读取,并全局替换=\n为空。


Kus*_*nda 6

使用sed检测到结尾线=。当找到这样的一行时,下一行被添加到编辑缓冲区中的当前行,并用一个换行符将两者分开,=删除 和 换行符,并打印连接的行。

$ cat file
Apple
Banana milkshake
Cherry =
Pie
Run Code Online (Sandbox Code Playgroud)
$ sed '/=$/ { N; s/=\n//; }' file
Apple
Banana milkshake
Cherry Pie
Run Code Online (Sandbox Code Playgroud)

请注意,这不能处理所有以=. 为了处理它们,必须重复该过程(中间结果可以保存到临时文件、原始文件或简单地再次通过管道传输到同一命令)。

... 或者你可以在 中做一个显式循环sed

sed -e ':again' -e '/=$/ { N; s/=\n//' -e 'b again' -e '}' file
Run Code Online (Sandbox Code Playgroud)

测试:

$ cat file
Apple
Banana milkshake
Pie =
with a cherry =
on top
Run Code Online (Sandbox Code Playgroud)
$ sed -e ':again' -e '/=$/ { N; s/=\n//' -e 'b again' -e '}' file
Apple
Banana milkshake
Pie with a cherry on top
Run Code Online (Sandbox Code Playgroud)