如何在模式前插入换行符?

如何在行内的模式前插入换行符?

例如,这将插入一个新行 后面正则表达式模式。

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

除了模式的 在前面之外,我怎样才能做同样的事情呢?

给定这个示例输入文件,匹配的模式是电话号码。

some text (012)345-6789

应该成为

some text
(012)345-6789
305285 次浏览

在 sed 中,不能轻松地在输出流中添加换行符。你需要使用一个延续行,这有点尴尬,但是很管用:

$ sed 's/regexp/\
&/'

例如:

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


foo

详情请参阅 给你。如果你想要一些稍微不那么尴尬的东西,你可以尝试使用 perl -pe和匹配组代替 sed:

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


foo

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

在 sed 中,你可以用“1”,“2”,... ... 在你的模式中引用组。 因此,如果您正在寻找的模式是“ PATTERN”,并且您想在它的前面插入“ BEFORE”,您可以使用,无转义

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

也就是说。

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

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

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

编辑: 这似乎不工作的 OS X,除非你安装 gnu-sed

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

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

这将替换为 newline:

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

0 是 null,所以表达式被替换为 null (nothing) ,然后..。
N 是新行

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

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

这可以在 bashzsh中工作,并在 Linux 和 OS X 上进行测试:

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

通常,对于 $后跟单引号字符串文字的 bash执行 C 样式的反斜杠替换,例如,$'\t'被转换为文字选项卡。另外,sed 希望用反斜杠转义换行符,因此 \$之前。最后,美元符号本身不应该被引用,因此它被 shell 解释,因此我们在 $之前关闭引用,然后再打开它。

编辑 : 正如@mklement0在评论中所建议的那样,这也可以起到作用:

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

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

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

cat Somefile |tr ',' '\012'

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

为了在 Linux 上的输出流中插入一个新行,我使用:

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

file1所在地:

def

在 sed 就地替换之前,以及:

abc
def

在 sed 就地替换之后。请注意 \\\n的使用。如果模式中包含 ",则使用 \"转义。

在 Red Hat 的 vi 中,我能够仅使用 r 字符插入回车符。我相信这在内部执行‘ ex’而不是‘ sed’,但它与之类似,而 vi 可以是另一种进行批量编辑(如代码补丁)的方法。比如说。我在一个搜索词的周围使用了一个 if 语句,该语句坚持在大括号后返回回车符:

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

注意,我还让它插入了一些选项卡,使事情排列得更好。

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

这在 MAC 对我有用

sed -i.bak -e 's/regex/xregex/g' input.txt sed -i.bak -e 's/qregex/\'$'\nregex/g' input.txt

不管它是否完美..。

您可以像使用 sed 一样使用 perl 一行程序,它的优点是完全支持 Perl 正则表达式(这比使用 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}

我想你可以算出大括号里的数字是怎么回事。

此外,您可以使用正则表达式以外的分隔符。所以如果你需要匹配/你不需要逃避它。下面的任何一个都等效于我答案开头的正则表达式。理论上你可以用 任何角色代替标准。

perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'

最后几点想法。

使用 -ne而不是 -pe的行为类似,但不会自动打印结束。如果你想自己打印的话,它会很方便。例如,这里有一个 grep-like (m/foobar/是正则表达式匹配) :

perl -ne 'if (m/foobar/) {print}'

如果您发现处理换行很麻烦,并且希望它能够神奇地为您处理,那么添加 -l。但是对于使用新行的 OP 来说没有什么用处。

额外的提示——如果您已经安装了 pcre 软件包,那么它将与 pcregrep一起提供,pcregrep使用完全兼容 perl 的正则表达式。

嗯,刚刚转义的换行似乎可以在 sed的最新版本中工作(我使用的是 GNUsed 4.2.1) ,

dev:~/pg/services/places> echo 'foobar' | sed -r 's/(bar)/\n\1/;'
foo
bar
echo pattern | sed -E -e $'s/^(pattern)/\\\n\\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

该脚本使用单个 sed命令将换行 \n后跟另一行文本附加到文件的末尾。

您也可以使用 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

在我的例子中,下面的方法是有效的。

sed -i 's/playstation/PS4/' input.txt

可以这样写:

sed -i 's/playstation/PS4\nplaystation/' input.txt

PS4
游戏机

考虑在字符串文字中使用 N

  • Sed : is stream Editor

  • - i : 允许编辑源文件

  • + : Is 分隔符。

我希望以上信息对你有用。