需要帮助理解sed中的这个正则表达式

时间:2013-01-09 01:25:18

标签: regex linux sed

我发布了this question,有人回复了这个

sed '/^void.*{$/!b;:a;/\n}$/bb;$!{N;ba};:b;s/\n/&test1&/;s/\(.*\n\)\(.*\n\)/\1test2\n\2/' file

我是sed和regex的新手,我无法理解每个部分的功能。

我将尝试解释我所理解的内容,你们可以填补遗漏的内容。我会按角色去角色

  1. ^void.*{$ - 这意味着以void开头并以{
  2. 结尾的任何内容
  3. /!b;我没有得到它的作用。现在b适用于branching。什么是/在那里做什么
  4. :a;用于制作标签a
  5. /\n再次没有理解/那里
  6. }$ 结尾的
  7. }
  8. /bb我不明白
  9. $!表示如果不是文件结尾
  10. {N;没有得到它的意思,N意味着复制缓冲区中的下一行,但确实得到{
  11. :b没有得到它。 b用于分支,但不知道它在那里做什么 10。s/\n/&test1&/我认为用\ntest1\n取代\ n但不确定
  12. s/\(.*\n\)\(.*\n\)/\1test2\n\2/也不会得到这个

2 个答案:

答案 0 :(得分:2)

这个词:

/^void.*{$/!b

表示匹配^void.*{$,斜杠是正则表达式周围的正则表达式分隔符。所以你得到/^void.*{$/。如果在/regex/!中跟随匹配表达式后出现感叹号,则表示如果正则表达式not匹配,则执行以下命令。以下命令是b,它是分支。其中没有标签名称,在脚本末尾分支。总的来说,这个表达式尝试匹配^void.*{$(即,以void开头并以{结尾的行)并跳过(b)脚本的其余部分,以防匹配失败({ {1}})。

这件事:

!

启动标签:a;/\n}$/bb;$!{N;ba}; 并尝试匹配:a;(换行符和一行\n}$),该行再次包含在}中。在匹配时,它将(/regex/)分支到标签b(因此,b)。如果这不是输入的结尾(/regex/bb),则读取行$!并跳回标签a(N)。这里的卷曲对(即ba)创建一个块。这个块 如果{commands}为真,则作为一个整体执行,这意味着有更多的输入。所以$!只是意味着:

$!{N;ba}

答案 1 :(得分:2)

您可以将多个sed表达式与;字符链接在一起。以下分别介绍每一个。

第一个表达式/^void.*{$/!b在分隔/&#39}之间有一个匹配器表达式。匹配:

^ - 行的开头

void - 后跟字符" void"

.* - 后跟任何内容

{ - 后面是左卷曲

$ - 接着是行尾

第一个表达式中的修饰符!b表示如果匹配器不匹配,则中止sed评估。

:a表达式是一个标签。它与类似goto的sed功能一起使用,称为分支。我们将在下一个表达式中看到标签的使用方式。

表达式/\n}$/bb匹配:

\n - 换行符

} - 接着是右卷曲

$ - 接着是行尾

修饰符bb表示如果找到匹配项,"分支"到标签b。标签b在后面的表达式中定义为:b

$!{N;ba}表达式应该读作一个,即使它在中间有一个;。在这种情况下,curlies代表了一系列旨在一起执行的命令。

$! - 如果它不是输入的结尾

{ - 启动一组命令(在这种情况下,有两个命令)

N - 默默地读另一行

ba - 分支标记

} - 结束命令组

接下来是标签:b,当我们通过}表达式匹配单行/\n}$/bb时,我们会点击该标签。

最后有两种替代模式,它们都是非常标准的正则表达式。表达式之前的s实际上意味着s/find_this/replace_it_with_this/。在s/\n/&test1&/的情况下,我们有:

\n - 找到换行符

/ - 并将其替换为

& - 在第一个表达式中匹配的东西(在本例中为换行符)

test1 - 单词test1

& - 再次匹配的东西

所以基本上s/\n/&test1&/表示将\n替换为\ntest1\n

最后一个表达式类似,但引入了一些称为捕获的东西。 Captures让你仍然可以匹配所有内容,但保留\(\)之间的所有内容,以便在表达式的替换部分中使用。例如,如果给出s/a\(b\)c\(d\)e/\1 \2/的输入字符串,b d将输出abcde。在示例中,\1\2将替换为转义的parens bd中分别捕获的内容。

s - 这是替换模式:

/ - 找到

\( - 并放入\1替换变量

. - 任何事情

* - 及其任何数量

\n - 包括您遇到的第一个换行符

\) - (\1的捕获结束)

\( - 并放入\2替换变量

. - 任何事情

* - 及其任何数量

\n - 包括您遇到的第一个换行符

\) - (\2的捕获结束)

/ - 并用

替换所有内容

\1 - 捕获的第一件事,

test2\n - test2 \ n,

\2 - 第二件事就是抓住了。