Sed 地址范围中的空正则表达式有什么作用?

What Does an Empty Regular Expression in a Sed Address Range Do?

下面的命令sed -E '/# Section [134]/, // s/foo/bar/' <input_file>完成下面的

输入

# Section 1

- foo
- Unimportant Item

# Section 2

- foo
- Unimportant Item

# Section 3

- foo
- Unimportant Item

# Section 4

- foo
- Unimportant Item

# Section 5

- foo
- Unimportant Item

输出

# Section 1

- bar
- Unimportant Item

# Section 2

- foo
- Unimportant Item

# Section 3

- bar
- Unimportant Item

# Section 4

- bar
- Unimportant Item

# Section 5

- foo
- Unimportant Item

我不确定这个命令是如何工作的,特别是地址范围内的空正则表达式。到目前为止我的理解是 Sed 将首先查找文档中与以下正则表达式 /# Section [134]/ 匹配的部分,如果匹配,它将开始替换查找 foo 的匹配项并将它们替换为 bar。据我所知,地址范围的第二部分是停止点,但在本例中它是空的。我读到 here 一个空的正则表达式“重复最后一个正则表达式匹配”,但我不完全知道这意味着什么,或者它如何影响这个特定的 Sed 命令。地址范围如何知道停止点在每个部分之后? // 重复的是什么正则表达式?

使用空正则表达式是 shorthand 重复最新匹配的正则表达式。因此,您的脚本是 longhand

的缩写版本(更加地道,错误更少)
sed -E '/# Section [134]/,/# Section [134]/ s/foo/bar/' <input_file>

表示在以一次出现的正则表达式开始的行范围内执行替换 s/foo/bar/ ,直到下一次出现相同的正则表达式(如果有第三个出现则重新开始第四个等等)。

这在s///命令中也可用,所以一个相当常见的习语是

sed '/foo/ s//bar/'

表示搜索 foo,然后将 foo 替换为 bar。 (这个特定示例不是特别有用,但在某些情况下可以节省大量输入。)

让我将输入文件简化为:

Line1
Line2
Line3
Line4
Line5

测试脚本为:

sed -n "/[134]/,//p"

这将打印与您的测试结果相对应的所有行。 如前所述,空正则表达式重复前一个正则表达式,然后是 sed 命令 以上相当于:

sed -n "/[134]/,/[134]/p"

顺便说一句,sed 的地址范围运算符的工作原理如下:

  • 如果 left 地址匹配,returns true 无需 评估 right 地址在同一行(不像 awk 的范围运算符 条件立即在同一行上)。

让我们逐行看看运算符是如何工作的。

  • 在第一行Line1,左边的起始地址匹配并且 returns true.
  • 在第二行,右停止地址被评估没有 匹配然后操作员保留 true.
  • 第三行,右边的停止地址匹配就可以了 将状态更改为 false 打印该行之后)。
  • 第四行,左边的起始地址与 returns true 再一次。
  • 第五行右停止地址不匹配保持true.

如果将正则表达式更改为 /[135]/,您将看到不同的结果。 (第 1、2、3、5 行将跳过第 4 行打印。)