如何在一行中的模式之前插入换行符?
例如,这将在正则表达式模式后面插入一个换行符。
sed 's/regex/&\n/g'
我怎么能在模式前面做同样的事情?
给定这个示例输入文件,要匹配的模式是电话号码。
some text (012)345-6789
应该成为
some text
(012)345-6789
这适用于bash
and zsh
,在 Linux 和 OS X 上测试:
sed 's/regexp/\'$'\n/g'
通常,for$
后跟单引号中的字符串文字bash
执行 C 样式的反斜杠替换,例如$'\t'
被翻译为文字选项卡。另外, sed 希望你的换行文字用反斜杠转义,因此是\
before $
。最后,不应该引用美元符号本身,以便它被 shell 解释,因此我们在 the 之前关闭引用$
,然后再次打开它。
编辑:正如@mklement0 评论中所建议的,这也有效:
sed $'s/regexp/\\\n/g'
这里发生的是:整个 sed 命令现在是一个 C 样式的字符串,这意味着 sed 需要放置在新行文字之前的反斜杠现在应该用另一个反斜杠转义。虽然更具可读性,但在这种情况下,您将无法进行 shell 字符串替换(不会再次使其变得丑陋。)
其他一些答案不适用于我的 sed 版本。切换位置&
并\n
确实有效。
sed 's/regexp/\n&/g'
编辑:这似乎不适用于 OS X,除非您安装gnu-sed
.
在 sed 中,您不能轻易在输出流中添加换行符。您需要使用续行,这很尴尬,但它有效:
$ sed 's/regexp/\
&/'
例子:
$ echo foo | sed 's/.*/\
&/'
foo
有关详细信息,请参见此处。如果您想要稍微不那么尴尬的东西,您可以尝试使用perl -pe
匹配组而不是 sed:
$ echo foo | perl -pe 's/(.*)/\n$1/'
foo
$1
指正则表达式中的第一个匹配组,其中组在括号中。
在我的 Mac 上,以下内容插入一个 'n' 而不是换行符:
sed 's/regexp/\n&/g'
这替换为换行符:
sed "s/regexp/\\`echo -e '\n\r'`/g"
echo one,two,three | sed 's/,/\
/g'
您可以像使用 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
\(
or\)
匹配一个文字括号,并\d
匹配一个数字。
更好的:
\(\d{3}\)\d{3}-\d{4}
我想您可以弄清楚大括号中的数字在做什么。
此外,您可以为您的正则表达式使用除 / 以外的分隔符。所以如果你需要匹配 / 你不需要逃避它。以下任何一项都相当于我回答开头的正则表达式。理论上,您可以用 任何字符替换标准 / 的。
perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'
几个最后的想法。
using-ne
而不是-pe
类似的行为,但不会在最后自动打印。如果您想自己打印,它会很方便。例如,这是一个类似 grep 的(m/foobar/
是一个正则表达式匹配):
perl -ne 'if (m/foobar/) {print}'
如果您发现处理换行符很麻烦,并且希望为您神奇地处理它,请添加-l
. 不过,对于使用换行符的 OP 来说没有用。
额外提示 - 如果您安装了 pcre 包,它会附带pcregrep
,它使用完全兼容 perl 的正则表达式。
在这种情况下,我不使用 sed。我用 tr。
cat Somefile |tr ',' '\012'
这需要逗号并将其替换为回车符。
嗯,刚刚转义的换行符似乎在更新的版本中工作sed
(我有 GNU sed 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/'
在 El Captitan 的()
支持下运行良好
为了在 Linux 上的输出流中插入换行符,我使用了:
sed -i "s/def/abc\\\ndef/" file1
在哪里file1
:
def
在 sed 就地替换之前,并且:
abc
def
在 sed 就地替换之后。请注意使用\\\n
. 如果模式"
里面有一个,使用 . 转义\"
。
就我而言,以下方法有效。
sed -i 's/playstation/PS4/' input.txt
可以写成:
sed -i 's/playstation/PS4\nplaystation/' input.txt
PS4
游戏机
考虑在字符串文字中使用\\n时使用它。
sed : 是流编辑器
-i : 允许编辑源文件
+:是分隔符。
我希望以上信息对您有用。
在 sed 中,您可以使用“\1”、“\2”、...来引用模式中的组。因此,如果您要查找的模式是“PATTERN”,并且您想在其前面插入“BEFORE” ,你可以使用,没有转义
sed 's/(PATTERN)/BEFORE\1/g'
IE
sed 's/\(PATTERN\)/BEFORE\1/g'
sed -e 's/regexp/\0\n/g'
\0是空值,因此您的表达式被替换为空值(无),然后...
\n是新行
在某些风格的 Unix 上不起作用,但我认为这是解决您问题的方法。
echo "Hello" | sed -e 's/Hello/\0\ntmow/g'
Hello
tmow
您也可以使用 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
这适用于我的 MAC
sed -i.bak -e 's/regex/xregex/g' input.txt sed -i.bak -e 's/qregex/\'$'\nregex/g' input.txt
Dono 是否是完美的...
在阅读了这个问题的所有答案后,我仍然尝试了很多次才能获得以下示例脚本的正确语法:
#!/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
在 Red Hat 上的 vi 中,我能够仅使用 \r 字符插入回车。我相信这在内部执行“ex”而不是“sed”,但它是相似的,vi 可以是另一种进行批量编辑(例如代码补丁)的方式。例如。我用一个 if 语句包围了一个搜索词,该语句坚持在大括号后回车:
:.,$s/\(my_function(.*)\)/if(!skip_option){\r\t\1\r\t}/
请注意,我还让它插入了一些标签以使事情更好地对齐。