Command line 如何匹配sed中的多个地址?

Command line 如何匹配sed中的多个地址?,command-line,sed,Command Line,Sed,我想对与多个命令的和或或匹配的任何行执行一些sed命令:例如,sed'50,70/abc/d'将删除范围50,70中匹配/abc/的所有行,或者一种不用重新键入s/compacted/regex/就可以执行sed-e'10,20s/complex/regex/'-e'30,40s/complex/regex/的方法,我不认为sed具有多个选择标准的功能,我的建议是升级到awk,在那里您可以执行以下操作: awk 'NR >= 50 && NR <= 70 &&

我想对与多个命令的
匹配的任何行执行一些
sed
命令:例如,
sed'50,70/abc/d'
将删除范围
50,70
中匹配
/abc/
的所有行,或者一种不用重新键入
s/compacted/regex/
就可以执行
sed-e'10,20s/complex/regex/'-e'30,40s/complex/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", $0); print }'
awk'NR>=50&&NR=10和NR=30&&NR逻辑与
部分可以使用大括号完成:

sed '50,70{/abc/d;}'
此外,大括号可以嵌套在多个
条件下

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

逻辑或
部件可以通过分支处理:

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/complex/regex/

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

使用GNU
sed
,上述语法可以稍微缩短为:

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

要删除与复杂正则表达式和GNU sed相匹配的10到20行和30到40行,请执行以下操作:

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


bA
:跳转到标签
:A

b
:无标签跳转->跳转到脚本末尾


d
:delete line

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

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

(NR>=50&&NR=10&&NR=30&&NR在BSD
sed
中使用分号也可以。GNU
sed
将允许您省略分号;BSD
sed
对我不起作用。通过嵌套大括号(如
sed'1~2{50,70{/abc/p}),似乎也可以使用>2个标准“
@JonathanLeffler一如既往地感谢您的编辑和提供的信息。只需稍加修改,您就可以完成第二部分:
sed-e'10,40{21,29!s/complex/regex/;}”
。它选择第10行到第40行,但只将替换项应用于第21到第29行以外的行(即10到第20行和第30到第40行)。
awk '
(NR>=50 && NR<=70) && /abc/ { next }
(NR>=10 && NR<=20) || (NR>=30 && NR<=40) { sub(/complicated/,"regex") }
{ print }
' file