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 行打印。)
下面的命令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
,左边的起始地址匹配并且 returnstrue
. - 在第二行,右停止地址被评估没有
匹配然后操作员保留
true
. - 第三行,右边的停止地址匹配就可以了
将状态更改为
false
( 在 打印该行之后)。 - 第四行,左边的起始地址与
returns
true
再一次。 - 第五行右停止地址不匹配保持
true
.
如果将正则表达式更改为 /[135]/
,您将看到不同的结果。
(第 1、2、3、5 行将跳过第 4 行打印。)