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

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

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

我希望将=以下一行结尾的每一行连接起来。任何其他换行符应保持不变。

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

输入示例:

Apple
Banana milkshake
Cherry =
Pie

应该变成:

Apple
Banana milkshake
Cherry Pie

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

答案1

使用awk

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

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


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

sed -z 's/=\n//g' file

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

答案2

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

$ cat file
Apple
Banana milkshake
Cherry =
Pie
$ sed '/=$/ { N; s/=\n//; }' file
Apple
Banana milkshake
Cherry Pie

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

...或者您可以在以下位置执行显式循环sed

sed -e ':again' -e '/=$/ { N; s/=\n//' -e 'b again' -e '}' file

测试:

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

答案3

sed:

sed -e ':a' -e '$!N;s/=\n//;t a' -e 'P;D' file

GNU sed:

sed ':a;N;s/=\n//;ta;P;D' file

GNU awk:

awk '1' RS='=\n' ORS= file

珀尔:

perl -pe 's/=\n//' file

如果输入的最后一行以 结尾=<newline>,awk 或 perl 会删除它,sed 不会。

答案4

我希望将以 = 结尾的每一行与下一行连接起来。

更新

awk '/=$/ {line=line $0;sub(/=$/,"",line);next}{$0= line $0;print $0;line=""} END{if (line) print line}' file
Apple
Banana milkshake
Cherry Pie

还测试了连接=以下一行结尾的每行(记录)或连接全部以下=一行结尾的多个连续行(记录)。一行或多行=是否位于文件末尾(任何位置)

这段代码:

  • 代码的第一部分(在 之前next)连接行=并将其保存在 var 中linesub()替换=""或空字符串(将其删除)。
  • 第二部分(after next)将 var 的内容line与下一行(即当前记录)连接起来,打印它并将空值赋给 var。
  • END 部分打印该记录或=文件末尾的记录。
  • next声明。这里不匹配的行/=$/将由第二个代码块处理。但是,如果文件以带有 的行(或更多行)结尾=,则第二个代码块不会执行,但我们可以在该END部分中打印该行或行。

例如,我们可以使用假定食谱的以下数据来品尝所有这些:

cat supposed-recipe.txt 
Cherry Pie Smoothie. =
This cherry smoothie =
tastes just like...

Ingredients:
Greek yogurt, plain non-fat, =
unsweetened milk, =
unsalted cashews,  =
etc.

And also:
1 pinch salt, =
and oats.
1 teaspoon =
vanilla extract,
fresh =
lemon juice.
1 teaspoon =
cinnamon, =
and frozen =
sweet cherries.

Optional:
2 teaspoons =
syrup or honey, =
to sweeten if wanted.

...and, if you want,
1 teaspoon chia seeds =
or similar. =
awk '/=$/ {line=line $0;sub(/=$/,"",line);next}{$0= line $0;print $0;line=""} END{if (line) print line}' supposed-recipe.txt

Cherry Pie Smoothie. This cherry smoothie tastes just like...

Ingredients:
Greek yogurt, plain non-fat, unsweetened milk, unsalted cashews,  etc.

And also:
1 pinch salt, and oats.
1 teaspoon vanilla extract,
fresh lemon juice.
1 teaspoon cinnamon, and frozen sweet cherries.

Optional:
2 teaspoons syrup or honey, to sweeten if wanted.

...and, if you want,
1 teaspoon chia seeds or similar.

相关内容