如何使用grep提取多段ul与/ul之间的内容?
提取文本中ul与/ul之间的内容
嘿,我来帮你搞定这个提取需求!你想要从那段混杂无关内容的文本里,精准抽出所有ul ... /ul的片段,其实你的思路是对的,只是可能需要一点点调整来适配不同环境或者文本格式。
解决方案
1. 用GNU grep(推荐)
如果你的系统是Linux,或者已经安装了GNU grep(比如macOS上通过Homebrew安装的ggrep),直接用你写的正则加上-oP选项就能实现;要是文本里有换行,还可以加上-z让grep把整个文本当作单行处理:
# 单行文本直接提取 echo "not what i want ul text1 text1 /ul not what i want not what i want ul texttext2 texttext2 texttext2 /ul not what i want" | grep -oP 'ul.*?/ul'
执行后会输出:
ul text1 text1 /ul ul texttext2 texttext2 texttext2 /ul
如果你希望把结果合并成同一行(和你期望的输出格式一致),可以用xargs来拼接:
echo "not what i want ul text1 text1 /ul not what i want not what i want ul texttext2 texttext2 texttext2 /ul not what i want" | grep -oP 'ul.*?/ul' | xargs
这样就能得到你想要的:
ul text1 text1 /ul ul texttext2 texttext2 texttext2 /ul
2. 适配BSD grep(比如macOS默认grep)
如果你的grep不支持-P选项(比如macOS自带的BSD grep),可以用awk来实现相同效果:
echo "not what i want ul text1 text1 /ul not what i want not what i want ul texttext2 texttext2 texttext2 /ul not what i want" | awk '{ while (match($0, /ul[^\/]*\/ul/)) { print substr($0, RSTART, RLENGTH) $0 = substr($0, RSTART + RLENGTH) } }' | xargs
小提示
.*?是非贪婪匹配,它会匹配从ul到最近的/ul的内容,正好符合你提取每个独立片段的需求- 如果文本里有换行,记得给grep加上
-z选项,否则.*无法跨换行匹配
内容的提问来源于stack exchange,提问作者Le Thuan
相关产品推荐
相关产品推荐

