如何在Bash中提取嵌套双括号内的字符串?无需循环可行吗?
如何用Bash提取嵌套双括号[[ ]]中的目标字符串(无循环实现)
你的问题核心在于嵌套的[[ ]]结构——基础的贪婪正则会直接匹配最外层的[[到最后一个]],导致漏掉内部的目标字符串。下面给你两个无需Bash循环的解决方案:
方法一:用Perl递归正则(推荐,处理嵌套更可靠)
Perl的正则支持递归匹配,可以精准识别嵌套的括号结构,一步到位提取目标内容:
echo '[[TargetString1:SomethingIDontWantAfterColon[[TargetString2]]]]' | perl -nle 'while (/\[\[(.*?)(?=(?:\[\[(?R)\]\]|[^\[\]])*\]\])/g) { $match = $1; $match =~ s/:.*//; print $match }'
原理说明:
\[\[(.*?)(?=(?:\[\[(?R)\]\]|[^\[\]])*\]\]:递归匹配所有[[...]]块,不管嵌套多少层。(?R)表示递归调用整个正则,用来识别内部的嵌套括号。$match =~ s/:.*//:对每个匹配到的内容,去掉冒号及后面不需要的部分。- 运行后直接输出:
TargetString1 TargetString2
方法二:用Grep+Sed+Cut组合
如果你的环境里有GNU Grep(支持PCRE模式-P),也可以用管道组合命令实现:
echo '[[TargetString1:SomethingIDontWantAfterColon[[TargetString2]]]]' | grep -oP '\[\[(?:(?!\[\[|\]\]).|(?R))*\]\]' | sed 's/^\[\[//; s/\]\]$//' | cut -d ':' -f1
原理说明:
grep -oP '\[\[(?:(?!\[\[|\]\]).|(?R))*\]\]':提取所有独立的[[...]]块(包括嵌套的),输出:[[TargetString1:SomethingIDontWantAfterColon[[TargetString2]]]] [[TargetString2]]sed 's/^\[\[//; s/\]\]$//':去掉每个块首尾的[[和]]。cut -d ':' -f1:截取冒号前的部分,得到最终目标字符串。
为什么你之前的命令失效?
你用的grep -o -P '(?<=\[\[).*(?=\]\])'是贪婪匹配,会从第一个[[直接匹配到最后一个]],得到的内容是TargetString1:SomethingIDontWantAfterColon[[TargetString2,自然提取不到内部的TargetString2。
内容的提问来源于stack exchange,提问作者once
相关产品推荐
相关产品推荐

