不是如何在一行之前插入换行符。这是在询问如何在一行中的模式之前插入换行符。
例如,
sed 's/regexp/&\n/g'
将在正则表达式模式后插入换行符。
我怎样才能在模式面前做同样的事情?
这是一个示例输入文件
somevariable (012)345-6789
应该成为
somevariable
(012)345-6789
答案 0 :(得分:152)
这适用于bash
,在Linux和OS X上测试过:
sed 's/regexp/\'$'\n/g'
通常,对于$
后跟单引号bash
中的字符串文字,执行C样式的反斜杠替换,例如$'\t'
被翻译为文字标签。另外,sed希望使用反斜杠转义新换行文字,因此\
之前为$
。最后,美元符号本身不应该被引用,以便它由shell解释,因此我们在$
之前关闭引用,然后再次打开它。
修改:正如@ mklement0在评论中所建议的那样,这也有效:
sed $'s/regexp/\\\n/g'
这里发生的是:整个sed命令现在是一个C风格的字符串,这意味着sed需要在新行文字现在应该用另一个反斜杠进行转义之前放置的反斜杠。虽然更具可读性,但在这种情况下,您将无法进行shell字符串替换(不会再次使其难看。)
答案 1 :(得分:38)
其他一些答案对我的sed版本不起作用。
切换&
和\n
的位置确实有效。
sed 's/regexp/\n&/g'
编辑:这似乎不适用于OS X,除非您安装gnu-sed
。
答案 2 :(得分:32)
在sed中,您无法轻松地在输出流中添加换行符。你需要使用一个很难的延续线,但它可以工作:
$ sed 's/regexp/\
&/'
示例:
$ echo foo | sed 's/.*/\
&/'
foo
有关详细信息,请参阅here。如果您想要稍微不那么尴尬的话,可以尝试将perl -pe
用于匹配组而不是sed:
$ echo foo | perl -pe 's/(.*)/\n$1/'
foo
$1
是指正则表达式中第一个匹配的组,其中组在括号中。
答案 3 :(得分:28)
在我的Mac上,以下插入单个' n'而不是换行:
sed 's/regexp/\n&/g'
这取代了换行符:
sed "s/regexp/\\`echo -e '\n\r'`/g"
答案 4 :(得分:14)
echo one,two,three | sed 's/,/\
/g'
答案 5 :(得分:9)
在这种情况下,我不使用sed。我用tr。
cat Somefile |tr ',' '\012'
这将使用逗号并将其替换为回车符。
答案 6 :(得分:8)
你可以使用perl one-liners,就像你使用sed一样,具有完全perl regular expression支持的优势(这比你用sed获得的功能强大得多)。 * nix平台上的变化也很小 - perl通常是perl。所以你可以不再担心如何使你的特定系统的sed版本做你想要的。
在这种情况下,您可以
perl -pe 's/(regex)/\n$1/'
-pe
将perl置于“执行和打印”循环中,就像sed的正常操作模式一样。
'
引用其他所有内容,以便shell不会干扰
()
是一个分组运算符。替换右侧的$1
打印出这些内容中匹配的内容。
最后,\n
是换行符。
无论您是否使用括号作为分组运算符,都必须转义要匹配的任何括号。因此,匹配上面列出的模式的正则表达式将类似于
\(\d\d\d\)\d\d\d-\d\d\d\d
\(
或\)
与文字符号匹配,\d
与数字匹配。
更好:
\(\d{3}\)\d{3}-\d{4}
我想你可以弄清楚括号中的数字是做什么的。
此外,您可以使用除/之外的分隔符作为正则表达式。所以如果你需要匹配/你不需要逃避它。下面的任何一个都等同于我答案开头的正则表达式。从理论上讲,你可以用any character代替标准。
perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'
额外提示 - 如果您安装了pcre软件包,它会附带pcregrep
,它使用完全兼容perl的正则表达式。
答案 7 :(得分:4)
嗯,刚刚转义的换行符似乎适用于sed
的更新版本(我有GNU sed 4.2.1),
dev:~/pg/services/places> echo 'foobar' | sed -r 's/(bar)/\n\1/;'
foo
bar
答案 8 :(得分:3)
要在Linux上向输出流插入换行符,我使用了:
sed -i "s/def/abc\\\ndef/" file1
file1
的位置:
def
在sed就地替换之前,并且:
abc
def
sed就地更换后。请注意使用\\\n
。如果模式中包含"
,请使用\"
进行转义。
答案 9 :(得分:3)
echo pattern | sed -E -e $'s/^(pattern)/\\\n\\1/'
使用()
支持
答案 10 :(得分:2)
就我而言,以下方法有效。
sed -i 's/playstation/PS4/' input.txt
可以写为:
sed -i 's/playstation/PS4\nplaystation/' input.txt
PS4
游戏机
考虑在字符串文字中使用 \\ n 。
sed :是流编辑器
-i :允许编辑源文件
+ :是定界符。
我希望以上信息对您有用。
答案 11 :(得分:2)
您也可以使用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
答案 12 :(得分:1)
在sed中,您可以使用“\ 1”,“\ 2”,....引用模式中的组。 因此,如果您要查找的模式是“PATTERN”,并且您想要在其前面插入“BEFORE”,则可以使用,无法逃避
sed 's/(PATTERN)/BEFORE\1/g'
即。
sed 's/\(PATTERN\)/BEFORE\1/g'
答案 13 :(得分:1)
在阅读了这个问题的所有答案之后,我仍然需要多次尝试才能获得以下示例脚本的正确语法:
#!/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
后跟另一行文本附加到文件末尾。
答案 14 :(得分:1)
sed -e 's/regexp/\0\n/g'
\ 0 是null,所以你的表达式被替换为null(无)然后......
\ n 是新行
在某些版本的Unix上不起作用,但我认为这是你问题的解决方案。
echo "Hello" | sed -e 's/Hello/\0\ntmow/g'
Hello
tmow
答案 15 :(得分:0)
这适用于我的MAC
sed -i.bak -e 's/regex/xregex/g' input.txt sed -i.bak -e 's/qregex/\'$'\nregex/g' input.txt
Dono是否是完美的...
答案 16 :(得分:0)
在Red Hat的vi中,我只能使用\ r字符插入回车符。我认为这在内部执行'ex'而不是'sed',但它类似,vi可以是另一种进行批量编辑的方法,例如代码补丁。例如。我围绕一个搜索术语,其中if语句坚持在括号后回车:
:.,$s/\(my_function(.*)\)/if(!skip_option){\r\t\1\r\t}/
请注意,我还插入了一些标签以使事情更好地对齐。