如何使用sed命令将换行符(“\n”)替换为空格(“”)?
我尝试过:
sed 's#\n# #g' file
sed 's#^$# #g' file
如何修复?
如何使用sed命令将换行符(“\n”)替换为空格(“”)?
我尝试过:
sed 's#\n# #g' file
sed 's#^$# #g' file
如何修复?
当前回答
tr '\n' ' '
是命令。
简单易用。
其他回答
快速回答
sed ':a;N;$!ba;s/\n/ /g' file
:a创建标签“a”N将下一行附加到模式空间$! 如果不是最后一行,ba分支(转到)标记为“a”s替换,/\n/regex替换新行,//替换空格,/g全局匹配(尽可能多次)
sed将循环执行步骤1到3,直到到达最后一行,使所有行都符合模式空间,sed将替换所有字符
选择
与sed不同的是,所有备选方案都不需要到达最后一行即可开始流程
用bash,慢
while read line; do printf "%s" "$line "; done < file
使用perl,sed般的速度
perl -p -e 's/\n/ /' file
使用tr,比sed更快,只能替换为一个字符
tr '\n' ' ' < file
与粘贴类似,tr速度,只能替换为一个字符
paste -s -d ' ' file
具有awk,tr般的速度
awk 1 ORS=' ' file
其他替代方法如“echo$(<file)”速度较慢,仅适用于小文件,需要处理整个文件才能开始处理。
sed常见问题解答5.10的长答案
5.10.为什么不能使用转义符匹配或删除换行符序列为什么我不能使用\n匹配2行或更多行?
\n永远不会匹配行尾的换行符,因为在将换行符放入图案空间。要在图案空间中获得两条或多条线,请使用“N”命令或类似命令(如“H;…;g;”)。
Sed是这样工作的:Sed每次读取一行终止换行符,将剩余内容放入模式空间,其中sed脚本可以寻址或更改它,并且当模式空间打印时,将换行符附加到stdout(或文件)。如果用“d”或“d”完全或部分删除图案空间在这种情况下不添加换行符。因此,脚本如
sed 's/\n//' file # to delete newlines from each line
sed 's/\n/foo\n/' file # to add a word to the end of each line
将永远不会工作,因为尾随换行符在将线放入图案空间。为了执行上述任务,请改用以下脚本之一:
tr -d '\n' < file # use tr to delete newlines
sed ':a;N;$!ba;s/\n//g' file # GNU sed to delete newlines
sed 's/$/ foo/' file # add "foo" to end of each line
由于除了GNU sed之外的sed版本对模式缓冲区,Unix“tr”实用程序在这里是首选的。如果文件的最后一行包含换行符,GNUsed将添加输出的新行,但删除所有其他行,而tr将删除所有换行符。
要匹配包含两行或更多行的块,有三种基本选择:(1) 使用“N”命令将“下一行”添加到图案空间;(2) 至少使用两次“H”命令附加当前行到保留空间,然后从保留空间检索行x、g或g;或(3)使用地址范围(见上文第3.3节)以匹配两个指定地址之间的行。
选项(1)和(2)将\n放入模式空间可以根据需要寻址('s/ABC\nXYZ/字母表/g')。一个例子使用“N”删除行块的方法见第4.13节(“如何删除特定连续行的块?”)。这可以通过将delete命令更改为其他命令来修改示例否则,如“p”(打印)、“i”(插入)、“c”(更改)、“a”(追加)、,或“s”(替代)。
选项(3)不会将一个\n放入模式空间,但它会匹配一块连续的行,因此可能不匹配甚至需要\n来查找所需内容。自GNU sed以来3.02.80版现在支持以下语法:
sed '/start/,+4d' # to delete "start" plus the next 4 lines,
除了传统的“/从这里/,/到那里/{…}”范围地址,则可能完全避免使用。
我特别喜欢的解决方案是在保留空间中追加所有文件,并替换文件末尾的所有换行符:
$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'
foobar
然而,有人告诉我,在一些sed实现中,保持空间可能是有限的。
tr '\n' ' '
是命令。
简单易用。
也可以使用此方法:
sed 'x;G;1!h;s/\n/ /g;$!d'
解释
x - which is used to exchange the data from both space (pattern and hold).
G - which is used to append the data from hold space to pattern space.
h - which is used to copy the pattern space to hold space.
1!h - During first line won't copy pattern space to hold space due to \n is
available in pattern space.
$!d - Clear the pattern space every time before getting the next line until the
the last line.
Flow
当第一行从输入中获取时,进行交换,因此1进入保留空间,\n进入模式空间,将保留空间附加到模式空间,执行替换并删除模式空间。
在第二行中,进行交换,2到保持空间,1到模式空间,G将保持空间附加到模式空间中,h将模式复制到其中,进行替换并删除。此操作将继续,直到达到EOF并打印确切结果。
将此解决方案与GNU sed一起使用:
sed ':a;N;$!ba;s/\n/ /g' file
这将在循环中读取整个文件(':a;N;$!ba),然后用空格(s/\N//g)替换换行符。如果需要,可以简单地附加其他替换。
说明:
sed首先将除换行外的第一行读取到模式空间中。通过:a创建标签。通过N将新行和下一行附加到图案空间。如果我们在最后一行之前,请分支到创建的标签$!ba($!表示不在最后一行执行此操作。这是避免再次执行N所必需的,如果没有更多输入,则会终止脚本!)。最后,替换用模式空间(即整个文件)上的空格替换每一个换行符。
以下是与BSD和OS X的sed兼容的跨平台语法(根据@Benjie评论):
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
正如您所看到的,使用sed解决这个简单的问题是有问题的。要获得更简单和充分的解决方案,请参阅以下答案。