如何使用sed命令将换行符(“\n”)替换为空格(“”)?

我尝试过:

sed 's#\n# #g' file
sed 's#^$# #g' file

如何修复?


当前回答

三件事。

tr(或cat等)是绝对不需要的。(GNU)sed和(GNU)awk结合在一起,可以完成99.9%的文本处理。流!=基于行。ed是一个基于行的编辑器。sed不是。有关差异的更多信息,请参阅sed讲座。大多数人将sed误认为是基于行的,因为默认情况下,它对SIMPLE匹配的模式匹配并不十分贪婪-例如,当进行模式搜索并替换为一个或两个字符时,默认情况下它只替换找到的第一个匹配(除非全局命令另有规定)。如果它是基于行而不是基于STREAM的,甚至不会有全局命令,因为它一次只能计算行。尝试运行ed;你会注意到差异。如果您想要在特定行上迭代(例如在for循环中),ed非常有用,但大多数时候您只需要sed。尽管如此,sed-e“{:q;N;s/\N//g;t q}”文件在GNUsed版本4.2.1中运行良好。上述命令将用空格替换所有换行符。它很难看,输入起来有点麻烦,但它工作得很好。{}可以省略,因为它们只是出于理智的原因才被包括在内。

其他回答

是sed在“正常”替换之后引入了新的行。首先,它修剪新行字符,然后根据您的指示进行处理,然后引入新行。

使用sed,您可以为每个输入行用您选择的字符串替换修剪后的行(而不是新行字符)的“结尾”;但是,sed将输出不同的行。例如,假设您希望将“行尾”替换为“==”(比用单个空格替换更通用):

PROMPT~$ cat <<EOF |sed 's/$/===/g'
first line
second line
3rd line
EOF

first line===
second line===
3rd line===
PROMPT~$

要用字符串替换新行字符,可以低效地使用tr,如前所述,用“特殊字符”替换换行字符,然后使用sed用所需的字符串替换该特殊字符。

例如:

PROMPT~$ cat <<EOF | tr '\n' $'\x01'|sed -e 's/\x01/===/g'
first line
second line
3rd line
EOF

first line===second line===3rd line===PROMPT~$

用任何字符串替换换行符,并替换最后一个换行符

纯tr解决方案只能替换为单个字符,纯sed解决方案不能替换输入的最后一行。以下解决方案解决了这些问题,并且似乎对二进制数据是安全的(即使使用UTF-8语言环境):

printf '1\n2\n3\n' |
  sed 's/%/%p/g;s/@/%a/g' | tr '\n' @ | sed 's/@/<br>/g;s/%a/@/g;s/%p/%/g'

结果:

1<br>2<br>3<br>

另一种GNU sed方法,几乎与Zsolt Botykai的答案相同,但这使用了sed不太常用的y(音译)命令,这节省了一个字节的代码(后面的g):

sed ':a;N;$!ba;y/\n/ /'

人们可能希望y的运行速度比s快(也许以tr的速度,快20倍),但在GNU sed v4.2.2中,y比s慢4%左右。


更便携的BSD sed版本:

sed -e ':a' -e 'N;$!ba' -e 'y/\n/ /'

为什么我没有找到一个简单的awk解决方案?

awk '{printf $0}' file

printf将打印没有换行的每一行,如果您想用空格或其他分隔原始行:

awk '{printf $0 " "}' file
sed '1h;1!H;$!d
     x;s/\n/ /g' YourFile

这不适用于巨大的文件(缓冲区限制),但如果有足够的内存来保存文件,则非常有效。(更正H->1h;在@hilojack的好话之后1!H)

另一个在读取时更改新行的版本(更多的cpu,更少的内存)

 sed ':loop
 $! N
 s/\n/ /
 t loop' YourFile