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

Den*_*nis 125 shell sed

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

例如,

sed 's/regex/&\n/g'
Run Code Online (Sandbox Code Playgroud)

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

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

这是一个示例输入文件

some text (012)345-6789
Run Code Online (Sandbox Code Playgroud)

应该成为

some text
(012)345-6789
Run Code Online (Sandbox Code Playgroud)

moj*_*uba 165

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

sed 's/regexp/\'$'\n/g'
Run Code Online (Sandbox Code Playgroud)

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

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

sed $'s/regexp/\\\n/g'
Run Code Online (Sandbox Code Playgroud)

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

  • 另一个选择是使用_single_ [ANSI C-quoted string](http://www.gnu.org/software/bash/manual/bash.html#ANSI_002dC-Quoting):`sed $'s/regexp/\\ \n/g'`,它提高了可读性 - 唯一需要注意的是你需要_double_所有文字`\`字符. (11认同)
  • 如上所述,这些表达式完全用换行符替换正则表达式,而不是根据请求在现有行的中间插入换行符.以下是我使用此答案的修改形式在两个匹配模式之间插入换行符的方式:`sed'\(first match \)\(second match \)/\1 \'$'\n''\ 2/g' `.注意\n后面的两个单引号.第一个关闭"$`"部分,以便该行的其余部分不受其影响.没有这些引号,\ 2被忽略了. (7认同)
  • 这给了我在OSX上的"未替换模式中的未转义换行符". (5认同)
  • @Matt Gibson ......或者如果你在我的代码中忘记'$'\n之前的反斜杠. (3认同)

Den*_*nis 40

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

sed 's/regexp/\n&/g' 
Run Code Online (Sandbox Code Playgroud)

编辑:这似乎并没有在OS X上运行,除非你安装gnu-sed.

  • 我不确定这适用于所有版本的sed.我在我的Mac上试过这个并且\n只输出'n' (9认同)
  • 在阅读你的答案之前,我在工作中花了15分钟.去苹果吧! (3认同)
  • 对于那些使用自制软件的人:`brew install gnu-sed` 后跟 `gsed 's/regexp/\n&/g'` (3认同)
  • ...接着是`echo 'alias sed=gsed' >> ~/.bashrc` (3认同)

Tod*_*lin 32

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

$ sed 's/regexp/\
&/'
Run Code Online (Sandbox Code Playgroud)

例:

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

foo
Run Code Online (Sandbox Code Playgroud)

详情请见此处.如果你想要一些稍微不那么尴尬的东西,你可以尝试使用perl -pe匹配组而不是sed:

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

foo
Run Code Online (Sandbox Code Playgroud)

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

  • 这是你可以在Mac上插入换行符最不好看的东西(\n在mac上不起作用) (2认同)
  • @Andres :(主要)POSIX-features-only Sed实现,如OS X附带的BSD版本,不支持`s`函数调用的替换部分中的控制字符转义序列(与_GNU_ Sed实现不同,哪个).上述答案适用于两种实现; 有关所有差异的概述,请参阅[此处](http://stackoverflow.com/a/24276470/45375). (2认同)

Roa*_*tad 29

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

sed 's/regexp/\n&/g'
Run Code Online (Sandbox Code Playgroud)

这取代了换行符:

sed "s/regexp/\\`echo -e '\n\r'`/g"
Run Code Online (Sandbox Code Playgroud)

  • 请注意第二个代码插入一个特殊的换行代码LF CR(与MS-DOS CR LF相反)!类Unix操作系统和Mac OS X都只使用LF(`\n`). (2认同)
  • @mojuba:否:`\`echo \``将导致_empty string_,因为命令替换总是修剪所有尾随的换行符。无法使用命令替换直接插入单个换行符(并且插入`\ n \ r`-即附加的CR-是一个糟糕的主意)。 (2认同)

小智 15

echo one,two,three | sed 's/,/\
/g'
Run Code Online (Sandbox Code Playgroud)

  • 这个答案实际上是一个**解决方案而不是**bash**解决方案.任何使用像'$'\n'`这样的结构的东西都依赖于shell来生成换行符.这些解决方案可能不便携.这个是.当然,这也是tgamblin从2009年开始回答的第二个例子. (2认同)

小智 9

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

cat Somefile |tr ',' '\012' 
Run Code Online (Sandbox Code Playgroud)

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

  • 我发现这也有效:`cat Somefile | tr ',' '\n'` YMMV (2认同)

Dan*_*tts 9

你可以像使用sed一样使用perl单行程序,具有完全perl正则表达式支持的优势(这比sed得到的功能强大得多).*nix平台上的变化也很小 - perl通常是perl.所以你可以不再担心如何使你的特定系统的sed版本做你想要的.

在这种情况下,你可以做到

perl -pe 's/(regex)/\n$1/'
Run Code Online (Sandbox Code Playgroud)

-pe 将perl置于"执行和打印"循环中,就像sed的正常操作模式一样.

' 引用其他所有内容,以便shell不会干扰

()正则表达式周围是一个分组运算符. $1在替换的右侧打印出这些内容中匹配的内容.

最后,\n是换行符.

无论您是否使用括号作为分组运算符,您都必须转义要匹配的任何括号.所以匹配上面列出的模式的正则表达式就像是

\(\d\d\d\)\d\d\d-\d\d\d\d
Run Code Online (Sandbox Code Playgroud)

\(\)匹配文字paren,并\d匹配一个数字.

更好:

\(\d{3}\)\d{3}-\d{4}
Run Code Online (Sandbox Code Playgroud)

我想你可以弄清楚括号中的数字是做什么的.

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

perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'
Run Code Online (Sandbox Code Playgroud)

奖金提示 - 如果您安装了pcre软件包,它会附带-ne,它使用完全兼容perl的正则表达式.