4

我发布了这个问题,有人回答了这个

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. /!b;我不明白这是做什么的。现在b是为branching。那里在/做什么
  3. :a;用于制作标签a
  4. /\n再次不明白/那里
  5. }$}
  6. /bb我不明白
  7. $!表示如果不是文件结尾
  8. {N;没明白是什么意思,N 表示复制缓冲区中的下一行但确实得到了{
  9. :b没明白。b 用于分支,但不知道它在那里做什么 10.s/\n/&test1&/我认为它用 \n 替换\ntest1\n但不确定
  10. s/\(.*\n\)\(.*\n\)/\1test2\n\2/也不要得到这个
4

2 回答 2

2

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

第一个表达式 ,在分隔符's/^void.*{$/!b之间有一个匹配器表达式。/它匹配:

^- 行的开头

void- 后跟字符“void”

.*- 紧随其后

{- 后跟左卷曲

$- 紧随其后的是行尾

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

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

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

\n- 换行符

}- 紧随其后的是右卷曲

$- 紧随其后的是行尾

修饰符bb意味着如果找到匹配项,则“分支”到标签 b。标签 b 在后面的表达式中定义为:b

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

$!- 如果不是输入结束

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

N- 默读另一行

ba- 分支以标记 a

}- 结束命令组

接下来是 label ,当我们通过表达式:b单独匹配一行上的单个时,我们将点击它。}/\n}$/bb

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

\n- 找到换行符

/- 并将其替换为

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

test1- 单词 test1

&- 再次匹配的东西

所以基本上意味着用s/\n/&test1&/替换下一个。\n\ntest1\n

最后一个表达式类似,但引入了一个叫做捕获的东西。捕获让您仍然可以匹配所有内容,但保留所有内容以供在表达式的替换部分使用\(\)例如s/a\(b\)c\(d\)e/\1 \2/b d如果给定输入字符串abcde. 在示例中,\1\2分别替换为转义括号中捕获的内容,bd

s- 这是一个替换模式:

/- 寻找

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

.- 任何事物

*- 以及任何数量

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

\)- (捕获结束\1

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

.- 任何事物

*- 以及任何数量

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

\)- (捕获结束\2

/- 并将其全部替换为

\1- 捕获的第一件事,

test2\n- 测试2\n,

\2- 第二件事被抓住了。

于 2013-01-09T03:03:18.610 回答
2

这个词:

/^void.*{$/!b

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

这东西:

:a;/\n}$/bb;$!{N;ba};

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

If not end of input:
begin
   real line
   jump to label a
end
于 2013-01-09T02:13:24.003 回答