仅当前一行以反斜杠结尾时,如何将多行合并为一行?

How to merge Multiple lines into one line only if the previous line ends with backslash?

我有以下文件:

Hi
How \
are \ 
you\
?

Bye

我想要得到这个输出:

Hi
How are you?

Bye

我该怎么做?

假设\在每行的末尾,后面没有空格:

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

使用没有行尾 (-z) 的文件,然后替换 \ 和一个空的新行。

\ 转义换行符上加入行正是 shell 的 read 命令在省略其 -r 选项标志时将执行的操作。

下面是一个使用 read 不带 -r 标志读取输入文件并打印结果的示例:

input.txt

Hi
How \
are \
you\
?

Bye
#!/usr/bin/env sh

# shellcheck disable=SC2162 # Explicitly desired backslash escaping
while IFS= read line || [ -n "$line" ]; do
  printf %s\n "$line"
done <input.txt

实际打印结果:

Hi
How are you?

Bye

Bash的help read摘录:

-r do not allow backslashes to escape any characters

SshellCheck SC2162: read without -r will mangle backslashes

便携sed方式:

[STEP 101] $ cat file
Hi
How \
are \
you\
?

Bye
[STEP 102] $ sed -e :go -e '/\$/!b' -e 'N;s/\\n//;bgo' file
Hi
How are you?

Bye
[STEP 103] $

更新:

sed1line 页面上找到了一个更简洁的:

sed -e :a -e '/\$/N; s/\\n//; ta'

awk:

echo 'Hi
How \
are \
you\
?

Bye' | awk '/\$/ {sub(/\$/, ""); printf "%s", [=10=]; next} 1'

打印:

Hi
How are you?

Bye

如果 \ 后有尾随空格:

awk '/\[ \t]*$/ {sub(/\[ \t]*$/, ""); printf "%s", [=12=]; next} 1' file

perl:

perl -0777 -lpE 's/\\h*\n//g' file