如何使用sed命令将换行符(“\n”)替换为空格(“”)?
我尝试过:
sed 's#\n# #g' file
sed 's#^$# #g' file
如何修复?
如何使用sed命令将换行符(“\n”)替换为空格(“”)?
我尝试过:
sed 's#\n# #g' file
sed 's#^$# #g' file
如何修复?
当前回答
也可以使用标准文本编辑器:
printf '%s\n' '%s/$/ /' '%j' 'w' | ed -s file
注意:这会将结果保存回文件。
与这里的大多数sed答案一样,此解决方案的缺点是必须首先将整个文件加载到内存中。
其他回答
答案是:标签。。。
如何使用sed替换换行符?
…在命令行的freebsd 7.2中不起作用:
( echo foo ; echo bar ) | sed ':a;N;$!ba;s/\n/ /g' sed: 1: ":a;N;$!ba;s/\n/ /g": unused label 'a;N;$!ba;s/\n/ /g' foo bar
但如果您将sed脚本放在文件中或使用-e“构建”sed脚本。。。
> (echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g' foo bar
或
> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof
> (echo foo; echo bar) | sed -f x.sed
foo bar
也许OS X中的sed是类似的。
也可以使用此方法:
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 'H;$!d;x;:a;s/^((.).*)\2/\1 /;ta;s/.//' file
H命令在模式空间前面加一个换行符,然后将结果附加到保留空间。sed的正常流程是从每一行中删除以下换行符,因此这将在保留空间的开头引入一个换行符,并复制文件的其余部分。一旦文件被拖入保留空间,就用模式空间替换保留空间,然后使用模式匹配将所有原始换行替换为空格。最后,删除引入的换行符。
这样做的优点是,在sed命令中永远不会实际输入换行字符串。
备选方案:
sed 'H;$!d;x;y/\n/ /;s/.//' file
Or:
sed 'H;1h;$!d;x;y/\n/ /' file
这里是没有缓冲区的sed(适用于实时输出)。示例:在HTML中用<br/>break替换\n
echo -e "1\n2\n3" | sed 's/.*$/&<br\/>/'
快速回答
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,
除了传统的“/从这里/,/到那里/{…}”范围地址,则可能完全避免使用。