为什么 sed 中需要这些花括号?

为什么 sed 中需要这些花括号?

我想在 sed 中进行范围有限的搜索,所以我尝试了

sed -n '195,210 /add/ p' <file>

这给了

sed:-e 表达式 #1,字符 9:未知命令:`/'

纯粹作为猜测,我尝试添加花括号:

sed -n '195,210{/add/p}' <file>

它很成功,但我试图理解为什么它与添加的大括号一起工作。
我有点明白,在 bash 中,大括号可以分隔表达式(并可能增加其执行顺序),但在 sed 的情况下,这些大括号在做什么?

相关信息

$ sed --version
sed (GNU sed) 4.2.2

$ bash --version
GNU bash, version 4.3.11

答案1

根据POSIX标准的页上sed:

该脚本应包含以下形式的编辑命令:

[地址[,地址]]功能

在哪里function代表列表中的单字符命令动词在 sed 中编辑命令,后跟任何适用的参数。

因此,地址后的第一个非空白字符被视为命令动词 - 在您的特定情况下,它是/,因此错误:char 9: unknown command: '/'
下面进一步引用大括号:

[2地址] {编辑命令
编辑命令
...
}
    执行列表sed仅当选择阵列空间时才可以编辑命令。 ……

  [2地址] 表示允许的最大地址数为 2。

为了澄清上述观点,地址的部分sed(1)说:

Sed给出的命令可以不带地址,在这种情况下,将对所有输入行执行该命令;具有一个地址,在这种情况下,仅对与该地址匹配的输入行执行该命令;或者有两个地址,在这种情况下,将对与从第一个地址开始并继续到第二个地址的行的包含范围匹配的所有输入行执行该命令。关于地址范围需要注意的三件事:语法是 (即地址由逗号分隔); [...]addr1,addr2

GNU 信息页面 ( info sed)在“3.4 常用命令”下对{和 有着类似的描述:}

{命令}
    一组命令可以包含在{}字符之间。当您希望由单个地址(或地址范围)匹配触发一组命令时,这特别有用。

换句话说,大括号用于在同一地址应用多个命令或嵌套地址。
这里的标准不是很明确,但是左大括号{ 实际上是启动一组其他 sed 命令的命令(该组以右大括号结束})。

而且,冒着真正去的风险长话短说, 问题是195, 210, 和/add/都是地址sed三个地址不能调用任何命令。 因此,使命令起作用的方法是{在地址范围上调用命令195,210,然后(在该范围内)p在地址上调用命令/add/

答案2

根据sed花括号的文档,花括号用于将命令分组在一起。所以

sed -n '195,210{/add/p}' <file>

195,210首先被视为具有块命令的地址范围。然后,块命令由地址规范/add/和命令 print组成p

答案3

sed 语法如下

地址/命令。

所以195,210是你匹配的第一个地址,但是你想在这个范围内执行一个新的命令,即匹配“add”,然后打印。因此,您需要使用花括号对这个额外的命令进行分组。

相关内容