如何在图案前面插入换行符?

问题描述 投票:120回答:16

不是如何在一行之前插入换行符。这是在询问如何在一行中的模式之前插入换行符。

例如,

sed 's/regexp/&\n/g'

将在正则表达式模式后插入换行符。

我怎么能在模式面前做同样的事情呢?

这是一个示例输入文件

somevariable (012)345-6789

应该成为

somevariable
(012)345-6789
shell sed
16个回答
151
投票

这适用于在Linux和OS X上测试的bash

sed 's/regexp/\'$'\n/g'

一般来说,对于$后跟单引号中的字符串文字,bash执行C风格的反斜杠替换,例如, $'\t'被翻译成文字标签。另外,sed希望你的换行文字用反斜杠转义,因此\之前的$。最后,美元符号本身不应该被引用,以便它由shell解释,因此我们在$之前关闭报价然后再次打开它。

编辑:正如@ mklement0的评论中所建议的,这也适用:

sed $'s/regexp/\\\n/g'

这里发生的是:整个sed命令现在是一个C风格的字符串,这意味着sed需要在新行文字现在应该用另一个反斜杠转义之前放置的反斜杠。虽然更具可读性,但在这种情况下,您将无法进行shell字符串替换(不会再次使其难看。)


3
投票
echo pattern | sed -E -e $'s/^(pattern)/\\\n\\1/'

在Qazxsw poi的支持下,El Capitan工作得很好


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!

1
投票

在sed中,您可以使用“\ 1”,“\ 2”,....来引用模式中的组。所以如果您要查找的模式是“PATTERN”,并且您想要在其前面插入“BEFORE” ,你可以使用,没有逃脱

$ 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

sed 's/(PATTERN)/BEFORE\1/g'

1
投票
  sed 's/\(PATTERN\)/BEFORE\1/g'

\ 0是null,所以你的表达式被替换为null(无)然后...... \ n是新行

在某些版本的Unix上不起作用,但我认为这是你问题的解决方案。

sed -e 's/regexp/\0\n/g'

1
投票

在阅读了这个问题的所有答案之后,我仍然需要多次尝试才能获得以下示例脚本的正确语法:

echo "Hello" | sed -e 's/Hello/\0\ntmow/g'
Hello
tmow

该脚本使用单个#!/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后跟另一行文本附加到文件末尾。


0
投票

在Red Hat的vi中,我只能使用\ r \ n字符插入回车符。我认为这在内部执行'ex'而不是'sed',但它类似,vi可以是另一种进行批量编辑的方法,例如代码补丁。例如。我正在围绕一个搜索词,其中包含一个if语句,该语句在括号后坚持回车:

sed

请注意,我还插入了一些选项卡以使事情更好地对齐。


0
投票

这适用于我的MAC

:.,$s/\(my_function(.*)\)/if(!skip_option){\r\t\1\r\t}/

Dono是否是完美的......


38
投票

其他一些答案对我的sed版本不起作用。切换&\n的位置确实有效。

sed 's/regexp/\n&/g' 

编辑:这似乎不适用于OS X,除非您安装gnu-sed


31
投票

在sed中,您无法轻松地在输出流中添加换行符。你需要使用一个很难的延续线,但它有效:

$ sed 's/regexp/\
&/'

例:

$ echo foo | sed 's/.*/\
&/'

foo

有关详细信息,请参阅here。如果你想要一些稍微不那么尴尬的东西,你可以尝试使用perl -pe与匹配组而不是sed:

$ echo foo | perl -pe 's/(.*)/\n$1/'

foo

$1是指正则表达式中第一个匹配的组,其中组在括号中。


29
投票

在我的Mac上,以下插入一个'n'而不是换行符:

sed 's/regexp/\n&/g'

这取代了换行符:

sed "s/regexp/\\`echo -e '\n\r'`/g"

14
投票
echo one,two,three | sed 's/,/\
/g'

9
投票

在这种情况下,我不使用sed。我用tr。

cat Somefile |tr ',' '\012' 

这将使用逗号并将其替换为回车符。


8
投票

你可以像使用sed一样使用perl单行,具有完全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的正则表达式。


4
投票

嗯,刚刚逃过的新行似乎适用于更新版本的sed(我有GNU sed 4.2.1),

dev:~/pg/services/places> echo 'foobar' | sed -r 's/(bar)/\n\1/;'
foo
bar

3
投票

要在Linux上向输出流插入换行符,我使用了:

sed -i "s/def/abc\\\ndef/" file1

file1在哪里:

def

在sed就地替换之前,并且:

abc
def

在sed就地更换后。请注意使用\\\n。如果图案里面有",请使用\"逃脱。

© www.soinside.com 2019 - 2024. All rights reserved.