能否用sed替代grep -oP从API数据中提取指定单词?
问题:用sed替代grep提取API数据中的天气代码
我有一批API返回的XML格式数据,想要提取其中code属性里包含cloudy或rainy的内容,目前已经用grep实现了这个功能,想知道能不能用sed完成同样的操作。
现有grep命令:
grep "symbol id=" | grep -oP '(?<=code=").*?(?=")'
API数据样例:
<time datatype="forecast" from="2022-12-07T12:00:00Z" to="2022-12-07T13:00:00Z"> <location altitude="585" latitude="60.8941" longitude="10.5001"> <precipitation unit="mm" value="0.0" minvalue="0.0" maxvalue="0.0">. </precipitation> <symbol id="Cloud" number="4" code="cloudy"></symbol> </location> </time> <symbol id="Cloud" number="4" code="cloudy"></symbol> -- <time datatype="forecast" from="2022-12-07T12:00:00Z" to="2022-12-07T18:00:00Z"> <location altitude="585" latitude="60.8941" longitude="10.5001"> <precipitation unit="mm" value="0.0" minvalue="0.0" maxvalue="0.0">. </precipitation> <minTemperature id="TTT" unit="celsius" value="-9.8"></minTemperature> <maxTemperature id="TTT" unit="celsius" value="-7.6"></maxTemperature> <symbol id="PartlyCloud" number="3" code="partlycloudy_day"></symbol> </location> </time>
解答
当然可以用sed实现,以下是几种可行的写法:
1. 提取所有symbol标签的code属性值
这个命令和你现有的grep组合功能一致,先匹配包含symbol id=的行,再提取code="..."中的内容:
sed -n '/symbol id=/ s/.*code="\([^"]*\)".*/\1/p' 你的数据文件路径
-n:告诉sed只打印指定内容,不输出所有行/symbol id=/:仅处理包含该字符串的行s/.*code="\([^"]*\)".*/\1/p:用正则匹配整行,捕获code="和"之间的所有内容([^"]*表示匹配除双引号外的任意字符),替换为捕获到的内容并打印
2. 只提取包含cloudy/rainy的code属性值
如果只想保留包含cloudy或rainy的结果,可以在命令里增加过滤逻辑:
sed -n '/symbol id=/ { /code=".*\(cloudy\|rainy\).*/ s/.*code="\([^"]*\)".*/\1/p }' 你的数据文件路径
或者分两步处理,先提取所有code值再过滤:
sed -n '/symbol id=/ s/.*code="\([^"]*\)".*/\1/p' 你的数据文件路径 | grep -E 'cloudy|rainy'
注意事项
sed是基于逐行处理的工具,如果你的XML数据中code属性被拆分成多行(比如标签换行),sed可能无法正确捕获内容。这种情况下更推荐用XML专用工具(如xmllint配合xpath)处理,但如果数据格式稳定(每个symbol标签的code属性都在同一行),上述sed命令完全可以满足需求。
内容的提问来源于stack exchange,提问作者Arawelo
相关产品推荐
相关产品推荐

