如何在 sed 中“优先考虑”某些模式而不是其他模式?

如何在 sed 中“优先考虑”某些模式而不是其他模式?

我有这个 sed 过滤器:

/.*[1-9][0-9][0-9] .*/{
        s/.*\([1-9][0-9][0-9] .*\)/\1/
}

/.*[1-9][0-9] .*/{
        s/.*\([1-9][0-9] .*\)/\1/
}

/.*[0-9] .*/{    # but this is always preferred/executed
        s/.*\([0-9] .*\)/\1/
}

问题是前两个限制性更强,并且它们没有被执行,因为最后第三个更“强大”,因为它包括前两个。有没有办法让 sed 采取前两个,并带有“优先顺序”?喜欢

if the first matches
    do first things
elif the second matches
    do second things
elif the third matches
    do third things

答案1

在不知道这些正则表达式的目标是什么并且没有测试数据的情况下,您需要的是一个t分支,它将导致您sed分支到脚本的末尾,并在成功完成替换后跳过处理其余代码。

sed '/regexp1/ s/do/things/; t
     /regexp2/ s/do/things/; t
     /regexp3/ s/do/things/ ' infile

根据您使用的命令,您还可以使用b分支(无条件分支到指定的标签,或者如果省略标签则分支到脚本的末尾)sed -e '/regex/{ s/do/things/; b' -e '}; ...'


来自“man sed”:

t label
如果自上次读取输入行以来以及自上次 t 或 T 命令以来 as/// 已成功替换,则分支到 label;如果省略标签,则分支到脚本末尾。

b label
分支到标签;如果省略标签,则分支到脚本末尾。

答案2

你误解了正在发生的事情。 Sed 始终执行所有按顺序匹配的模式。问题在于最后一个模式正在重新编辑第一个模式的内容。

另外,如果 s/// 上的搜索模式与匹配模式相同,那么它就是多余的,并且您实际上并没有在这些模式之间进行不同的更改,那么您如何知道它运行的是哪一个呢?

相关内容