如何在sed的替换部分插入换行符?
此代码不起作用:
sed "s/\(1234\)/\n\1/g" input.txt > output.txt其中input.txt是:
test1234foo123bar1234output.txt应该是:
test
1234foo123bar
1234但我明白了:
testn1234foo123barn1234注:
这个问题专门针对Mac版本的"sed",社区注意到它的行为与Linux版本不同。
发布于 2011-05-24 14:44:03
您的sed版本显然不支持RHS中的\n (替换的右侧)。您应该阅读Eric维护的SED常见问题,以选择可能的解决方案之一。我建议先尝试插入文字换行符。
下面是它的引文。
4.1.如何在替换的RHS中插入换行符?
有些版本的sed允许将\n直接输入到RHS中,然后将RHS转换为输出时的换行符: sed、gsed302a+、gsed103 (带有-x开关)、sed15+、sedmod和UnixDOS sed。最简单的解决方案是使用其中一个版本。
对于sed的其他版本,请尝试以下方法之一:
(a)如果从Bourne键入sed脚本,如果脚本使用‘单引号’,则使用一个反斜杠\,如果脚本需要“双引号”,则使用两个反斜杠\\。在下面的示例中,请注意,第2行的前导>是由shell生成的,以提示用户输入更多内容。用户输入斜杠、单引号,然后输入以终止命令:
[sh-prompt]$ echo twolines | sed 's/two/& new\
>/'
two new
lines
[bash-prompt]$(b)使用脚本文件,脚本中有一个反斜杠\,后面紧跟一个换行符。这将在“替换”部分中嵌入一个换行符。示例:
sed -f newline.sed files
# newline.sed
s/twolines/two new\
lines/g有些版本的sed可能不需要尾随反斜杠。如果是的话,就把它移除。
(c)插入一个未使用的字符并通过tr传输输出:
echo twolines | sed 's/two/& new=/' | tr "=" "\n" # produces
two new
lines(d)使用G命令:
G在模式空间的末尾追加一个换行符,加上持有空间的内容。如果持有空间为空,则无论如何都会追加换行符。换行符以\n的形式存储在模式空间中,在那里可以通过分组\(...\)来寻址并移动到RHS中。因此,要更改前面使用的"twolines“示例,可以使用以下脚本:
sed '/twolines/{G;s/\(two\)\(lines\)\(\n\)/\1\3\2/;}'(e)插入整行,而不是拆分线:
如果一个人不是在改变行,而只是在一个模式之前或之后插入完整的行,那么这个过程就容易多了。使用i (插入)或a (追加)命令,通过外部脚本进行更改。若要在匹配正则表达式的每一行之前插入This line is new,请执行以下操作:
/RE/i This line is new # HHsed, sedmod, gsed 3.02a
/RE/{x;s/$/This line is new/;G;} # other seds上面的两个示例是从控制台输入的“一行”命令。如果使用sed脚本,则i\后面紧跟文字换行符将适用于sed的所有版本。此外,命令s/$/This line is new/只在持有空间已经为空(默认情况下为空)时才能工作。
若要在匹配正则表达式的每一行后面追加This line is new,请执行以下操作:
/RE/a This line is new # HHsed, sedmod, gsed 3.02a
/RE/{G;s/$/This line is new/;} # other seds若要在匹配正则表达式的每一行后面追加2行空白行:
/RE/{G;G;} # assumes the hold space is empty若要用5行空行替换匹配正则表达式的每一行,请执行以下操作:
/RE/{s/.*//;G;G;G;G;} # assumes the hold space is empty如果可能的话,(f)使用y///命令:
在某些Unix版本的sed (不是GNU!)上,尽管s///命令在RHS中不接受\n,但y///命令确实接受。如果Unix支持它,可以以这种方式插入aaa后的换行符(不能移植到GNU或其他sed ):
s/aaa/&~/; y/~/\n/; # assuming no other '~' is on the line!发布于 2011-05-24 14:43:42
solaris版本的sed I可以说服您这样做(在bash中):
echo test1234foo123bar1234 | sed 's/\(1234\)/\
\1/g'(你必须在反斜杠后直接放断线)。
在csh中,我不得不再加一个反斜杠:
echo test1234foo123bar1234 | sed 's/\(1234\)/\\
\1/g'Gnu版本的sed简单地使用\n
echo test1234foo123bar1234 | sed 's/\(1234\)/\n\1/g'发布于 2011-05-24 14:29:14
Perl提供了更丰富的“扩展”regex语法,在这里很有用:
perl -p -e 's/(?=1234)/\n/g'意思是“按照模式1234替换零宽度匹配的换行符”。这避免了使用反向引用捕获和重复表达式的部分。
https://stackoverflow.com/questions/6111679
复制相似问题