Answers:
可以在bash
和zsh
上运行,并在Linux和OS X上进行了测试:
sed 's/regexp/\'$'\n/g'
通常,对于$
单引号后面的字符串文字,请bash
执行C样式的反斜杠替换,例如$'\t'
转换为文字标签。另外,sed希望您的换行符用反斜杠转义,因此是\
before $
。最后,美元符号本身不应该用引号引起来,以便由外壳程序解释,因此我们在之前关闭引号$
,然后再次将其打开。
编辑:如@ mklement0的注释中所建议,这也可以正常工作:
sed $'s/regexp/\\\n/g'
这里发生的是:整个sed命令现在是C样式的字符串,这意味着sed所需要的反斜杠必须放在换行文字之前,而现在应使用另一个反斜杠进行转义。尽管更具可读性,但是在这种情况下,您将无法执行shell字符串替换(而不必再次使其难看)。
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
。请注意\ n后的两个单引号。第一个关闭“ $
”部分,以便该行的其余部分不受此影响。没有这些引号,\ 2被忽略。
其他一些答案对我的sed版本不起作用。切换的位置&
并\n
完成了工作。
sed 's/regexp/\n&/g'
编辑:除非您安装,否则这似乎在OS X上不起作用gnu-sed
。
brew install gnu-sed
随后是gsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
在sed中,您不能轻易在输出流中添加换行符。您需要使用一个续行,这很尴尬,但是可以使用:
$ sed 's/regexp/\
&/'
例:
$ echo foo | sed 's/.*/\
&/'
foo
有关详细信息,请参见此处。如果您想要一些不太尴尬的东西,可以尝试使用perl -pe
匹配组而不是sed:
$ echo foo | perl -pe 's/(.*)/\n$1/'
foo
$1
指正则表达式中的第一个匹配组,其中组在括号中。
perl -pi -e 's/(.*)/\n$1/' foo
在我的Mac上,以下代码插入一个'n'而不是换行符:
sed 's/regexp/\n&/g'
这将替换为换行符:
sed "s/regexp/\\`echo -e '\n\r'`/g"
sed -i '' -e ...
并且^M
插入符号M(ctrl + m)被写入文件时遇到问题。我最终使用了具有相同参数的perl。
\n
)。
echo...
and和newline的情况下也可以正常工作),我只是在vim中这样做。
sed "s/regexp/`echo`/g"
-这将产生单个LF而不是LF-CR
`echo`
将导致字符串为空,因为命令替换将始终修剪所有尾随的换行符。无法使用命令替换直接插入单个换行符(并且插入\n\r
-即附加的CR-是一个糟糕的主意)。
您可以像使用sed一样使用perl单行代码,它具有完整的perl正则表达式支持(比sed强大得多)的优点。* nix平台之间的差异也很小-perl通常是perl。因此,您不必担心如何使特定系统的sed版本执行您想要的操作。
在这种情况下,您可以
perl -pe 's/(regex)/\n$1/'
-pe
将perl置于“执行和打印”循环中,非常类似于sed的正常操作模式。
'
引用其他所有内容,以便外壳不会干扰
()
正则表达式周围是分组运算符。 $1
替换的右侧会打印出这些括号中匹配的内容。
最后\n
是换行符。
无论是否使用括号作为分组运算符,都必须转义要匹配的任何括号。因此,与您在上面列出的模式匹配的正则表达式将类似于
\(\d\d\d\)\d\d\d-\d\d\d\d
\(
或\)
匹配文字括号,并\d
匹配数字。
更好:
\(\d{3}\)\d{3}-\d{4}
我想您可以弄清楚括号中的数字在做什么。
另外,您可以对正则表达式使用/以外的定界符。因此,如果您需要匹配/您将不需要对其进行转义。下面的任何一个都相当于我回答开头的正则表达式。从理论上讲,您可以用 任何字符代替标准字符。
perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'
几个最后的想法。
使用-ne
代替-pe
行为类似,但不会在最后自动打印。如果您想自己打印,可以很方便。例如,这是一个类似grep的代码(m/foobar/
是正则表达式匹配项):
perl -ne 'if (m/foobar/) {print}'
如果发现处理换行很麻烦,并且希望为您神奇地处理换行,请添加-l
。不过,对于正在使用换行符的OP来说,它没有用。
额外提示-如果您安装了pcre软件包,则随附pcregrep
,它使用完全兼容perl的正则表达式。
要在Linux上插入换行符以输出流,我使用了:
sed -i "s/def/abc\\\ndef/" file1
在哪里file1
:
def
在sed就地更换之前,并且:
abc
def
sed就位后更换。请注意的使用\\\n
。如果图案"
内部有图案,请使用进行转义\"
。
sed
插入\n
而不是LF,因为它\\n
从外壳程序获取参数。---此代码的工作:sed -i "s/def/abc\ndef/" file1
。--- GNU sed version 4.2.1
,GNU bash, version 4.1.2(1) / 4.2.25(1)
(CentOS版本6.4 / Ubuntu的12.04.3)。
在sed中,您可以使用“ \ 1”,“ \ 2”,...来引用模式中的组。因此,如果要查找的模式是“ PATTERN”,并且您想在其前面插入“ BEFORE” ,可以使用,没有转义
sed 's/(PATTERN)/BEFORE\1/g'
即
sed 's/\(PATTERN\)/BEFORE\1/g'
您还可以使用awk来执行此操作,使用-v
提供的模式:
awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
这将检查一行是否包含给定的模式。如果是这样,它将在其开头添加新行。
看一个基本的例子:
$ cat file
hello
this is some pattern and we are going ahead
bye!
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
hello
this is some
pattern and we are going ahead
bye!
注意它将影响一行中的所有模式:
$ cat file
this pattern is some pattern and we are going ahead
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' d
this
pattern is some
pattern and we are going ahead
1
在Awk中用作的简写{print $0}
。原因是任何评估结果为True的条件都会触发Awk的默认操作,该操作包括打印当前记录。
在阅读完该问题的所有答案之后,我仍然花了很多时间才能为以下示例脚本获取正确的语法:
#!/bin/bash
# script: add_domain
# using fixed values instead of command line parameters $1, $2
# to show typical variable values in this example
ipaddr="127.0.0.1"
domain="example.com"
# no need to escape $ipaddr and $domain values if we use separate quotes.
sudo sed -i '$a \\n'"$ipaddr www.$domain $domain" /etc/hosts
该脚本\n
使用一个sed
命令在文件末尾附加一个换行符和另一行文本。
sed '/regex/G'