使用 sed 替换括号内的内容,即使有多个嵌套内容

Using sed to replace bracketed content even if multiple nested ones

我正在使用 sed 查找和删除带有左括号和右括号的文本表达式。

示例:sed -re 's/ SCYEXIT\([^)]+\)//g'

适用于空括号:SCYEXIT(' ') 但是我的一些文本行有两对方括号,上面的搜索失败了。

失败示例:SCYEXIT('/var/mqm/exits/SecExitSender(SecurityExit)') 结果是:')

有些括号是空的(' ') 或有内容 ('FN=/var/mqm/exits/sendexit.data') 甚至还有另一对括号 像 ('/var/mqm/exits/SecExitSender(SecurityExit)').

如何处理所有匹配的括号?

让事情更清楚。

我正在将 IBM MQ 从一个平台迁移到另一个平台,每个平台的参数存在一些差异。配置示例如下所示:

DEFINE QLOCAL ('postcard') SCYEXIT('/var/mqm/exits/SecExitSender(SecurityExit)') PROCESS(' ') PUT(ENABLED) DEFPRTY(0) REPLACE

这里我想去掉独立于后面一对括号内容的SCYEXITPROCESS属性。作为人类,您会立即理解我在这里用括号表示的意思。括号可以是空的,也可以有值,甚至是嵌套值。

我想要达到的效果是这样的:

DEFINE QLOCAL ('postcard') PUT(ENABLED) DEFPRTY(0) REPLACE

sed ':a 
    s/([^()][^()]*)//g
    t a'

使用[^()]代替[^)],重复替换直到没有一对匹配的大括号。

$ cat ip.txt 
SCYEXIT(' ')
DEFINE QLOCAL ('postcard') SCYEXIT('/var/mqm/exits/SecExitSender(SecurityExit)') PROCESS(' ') PUT(ENABLED) DEFPRTY(0) REPLACE
PROCESS(' ') asd
1 SCYEXIT(' ')
PROCESS(' ')
DEFINE QLOCAL ('postcard')

解决方案使用sed

$ sed -E 's/(SCYEXIT|PROCESS)\(\S+\)//g ; s/(SCYEXIT|PROCESS)\(.\s*.\)//g' ip.txt

DEFINE QLOCAL ('postcard')   PUT(ENABLED) DEFPRTY(0) REPLACE
 asd
1 

DEFINE QLOCAL ('postcard')
  • (SCYEXIT|PROCESS)\(\S+\) 表示 SCYEXITPROCESS 后跟 ( 和一个或多个非白色 space 字符并以 [=18= 结尾]
  • (SCYEXIT|PROCESS)\(.\s*.\) 表示 SCYEXITPROCESS 后跟 ( 然后是任意字符,任意数量的白色 space,另一个字符,最后是 ) --> 这会处理空括号
  • 对于非 GNU 版本,使用 [[:space:]][^[:space:]] 而不是 \s\S

如果perl可用,

perl -pe 's/(SCYEXIT|PROCESS)\(.*?\)( |$)//g' ip.txt

给出与 sed 解决方案相同的输出,除了在 SCYEXITPROCESS(如果存在)

的结束括号后删除 space