如何在 sed 中匹配多个地址?

How do I match multiple addresses in sed?

我想对匹配多个命令的 andor 的任何行执行一些 sed 命令:例如,sed '50,70/abc/d' 将删除所有行匹配 /abc/ 的范围 50,70,或者无需重新键入 s/compicated/regex/

即可执行 sed -e '10,20s/complicated/regex/' -e '30,40s/complicated/regex/ 的方法

我认为 sed 没有 多个 选择标准的设施,我的建议是升级到 awk,您可以做类似的事情:

awk 'NR >= 50 && NR <= 70 && /abc/ {next} {print}' inputFile
awk '(NR >= 10 and NR <= 20) || (NR >= 30 && NR <= 40) {
     sub("from-regex", "to-string", [=10=]); print }'

逻辑与

and部分可以用大括号完成:

sed '50,70{/abc/d;}'

此外,大括号可以嵌套用于多个 and 条件。

(以上是在 GNU sed 下测试的。BSD sed 可能在一些小但令人沮丧的细节上有所不同。)

逻辑或

or部分可以用分支处理:

sed -e '10,20{b cr;}' -e '30,40{b cr;}' -e b -e :cr -e 's/complicated/regex/' file
  • 10,20{b cr;}

    对于从 10 到 20 的所有行,我们分支到标签 cr

  • 30,40{b cr;}

    对于从 30 到 40 的所有行,我们分支到标签 cr

  • b

    对于所有其他行,我们跳过其余命令。

  • :cr

    这标记了标签cr

  • s/complicated/regex/

    这对分支到 cr 的行执行替换。

使用 GNU sed,上面的语法可以缩短为:

sed '10,20{b cr}; 30,40{b cr}; b; :cr; s/complicated/regex/' file

删除第 10 到 20 行和第 30 到 40 行与 GNU sed 匹配的复杂正则表达式:

sed -e '10,20bA;30,40bA;b;:A;s/complicated/regex/;d' file

或:

sed -e '10,20bA' -e '30,40bA' -e 'b;:A;s/complicated/regex/;d' file


bA: 跳转到标签 :A

b: 没有标签的跳转 -> 跳转到脚本结尾

d: 删除行

sed 非常适合在单行上进行简单替换,但对于其他任何事情,只需使用 awk 即可获得清晰度、健壮性、可移植性、可维护性等...

awk '
(NR>=50 && NR<=70) && /abc/ { next }
(NR>=10 && NR<=20) || (NR>=30 && NR<=40) { sub(/complicated/,"regex") }
{ print }
' file