使用 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
这里我想去掉独立于后面一对括号内容的SCYEXIT
和PROCESS
属性。作为人类,您会立即理解我在这里用括号表示的意思。括号可以是空的,也可以有值,甚至是嵌套值。
我想要达到的效果是这样的:
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+\)
表示 SCYEXIT
或 PROCESS
后跟 (
和一个或多个非白色 space 字符并以 [=18= 结尾]
(SCYEXIT|PROCESS)\(.\s*.\)
表示 SCYEXIT
或 PROCESS
后跟 (
然后是任意字符,任意数量的白色 space,另一个字符,最后是 )
--> 这会处理空括号
- 对于非 GNU 版本,使用
[[:space:]]
和 [^[:space:]]
而不是 \s
和 \S
如果perl
可用,
perl -pe 's/(SCYEXIT|PROCESS)\(.*?\)( |$)//g' ip.txt
给出与 sed
解决方案相同的输出,除了在 SCYEXIT
或 PROCESS
(如果存在)
的结束括号后删除 space
我正在使用 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
这里我想去掉独立于后面一对括号内容的SCYEXIT
和PROCESS
属性。作为人类,您会立即理解我在这里用括号表示的意思。括号可以是空的,也可以有值,甚至是嵌套值。
我想要达到的效果是这样的:
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+\)
表示SCYEXIT
或PROCESS
后跟(
和一个或多个非白色 space 字符并以 [=18= 结尾](SCYEXIT|PROCESS)\(.\s*.\)
表示SCYEXIT
或PROCESS
后跟(
然后是任意字符,任意数量的白色 space,另一个字符,最后是)
--> 这会处理空括号- 对于非 GNU 版本,使用
[[:space:]]
和[^[:space:]]
而不是\s
和\S
如果perl
可用,
perl -pe 's/(SCYEXIT|PROCESS)\(.*?\)( |$)//g' ip.txt
给出与 sed
解决方案相同的输出,除了在 SCYEXIT
或 PROCESS
(如果存在)