Unix下提取类XML文本中所有user标签name值的问题
解决提取XML类字符串中所有name属性值的问题
这个问题很典型,你原来的命令只拿到最后一个值,核心原因是sed里的.*属于贪婪匹配——它会尽可能多地抓取字符,最后只锁定到字符串里最后一个符合条件的8位数字。下面给你几个靠谱的解决办法,按需选择:
方法1:改进sed命令,全局匹配并输出所有结果
我们可以精准匹配name="后面的8位数字,同时加上全局替换标志g,让sed把每行里所有符合条件的内容都提取出来:
grep -o "<sample:Recipients>.*</sample:Recipients>" sample.txt | sed -n 's/.*name="\([0-9]\{8\}\)".*/\1/gp'
- 这里用
name="\([0-9]\{8\}\)"精准定位目标,避免误抓guid里的长串数字 g标志让sed全局处理每行里的所有匹配项p配合-n只输出匹配到的结果
方法2:用grep的Perl正则直接提取(最简洁)
如果你的grep支持Perl正则(大部分Linux发行版都支持),可以用-P参数直接定位并输出目标值,连sed都省了:
grep -oP 'name="\K[0-9]{8}' sample.txt
\K是Perl正则的小技巧,它会忽略\K前面匹配到的内容(也就是name="),直接输出后面的8位数字-o参数让grep只输出匹配到的部分,不用额外处理
方法3:用awk循环匹配(更灵活)
如果需要更复杂的文本处理逻辑,awk是个好选择,它可以循环遍历所有匹配项:
awk '{while(match($0, /name="([0-9]{8})"/, arr)) {print arr[1]; $0=substr($0, RSTART+RLENGTH)}}' sample.txt
match()函数会查找符合正则的内容,把捕获组存到arr数组里- 每次匹配后,我们截断字符串(
substr($0, RSTART+RLENGTH)),继续查找下一个匹配项,直到处理完整个行
内容的提问来源于stack exchange,提问作者Abhinav
相关产品推荐
相关产品推荐

