如何使用 sed 一次提取标记之间的多个模式?
Posted
技术标签:
【中文标题】如何使用 sed 一次提取标记之间的多个模式?【英文标题】:How to extract multiple patterns between tokens at once with sed? 【发布时间】:2018-11-02 05:09:48 【问题描述】:假设我有一个名为 inputFile 的文件,看起来像这样:
blahblah token substring token something else token substring2 token
整个文件只包含 1 长行。
我想用 sed (substring,substring2) 提取标记之间的子字符串。
此时我有:
[sed "s/^.* \?token\(.* \)token.* \?/\1/"][1] inputFile > outputFile
我根据这些问题尝试这样做,但不幸的是它只返回最后一个子字符串
Extract lines between 2 tokens in a text file using bash
How to replace multiple patterns at once with sed?
How to select lines between two patterns?
有解释的答案会很棒。
更新 实际输入代码:
<archive><message id="0"><receiver>apr</receiver><sender>gtr</sender><text>52333</text><sendTime>554</sendTime><deliveryTime>765</deliveryTime></message><message id="0"><receiver>apr</receiver><sender>gtr</sender><text>4332</text><sendTime>764</sendTime><deliveryTime>922</deliveryTime></message></archive>
预期输出:
apr gtr 52333
apr gtr 4332
【问题讨论】:
开头不是缺少<archive>
吗?
你必须添加在什么基础上输出到达..另外,如果它是有效的 xml,使用像 xmlstarlet 这样的 xml 解析器或带有 xml 模块的编程语言..
@kvantour 是的,确实
@MariuszBakun 我已经用提供请求输出的xmlstarlet
cmd 更新了我的答案。
【参考方案1】:
问题是sed
是贪婪的,所以如果你添加全局标志(g
),上面的命令只会返回substring2
:
您可以为此使用awk
,将字段分隔符FS
重新定义为字符串token
。这样你的字符串就在偶数场位置:
$ echo "blahblah token substring token something else token substring2 token" | \
awk -F 'token' 'for(i=2;i<=NF;i+=2) print $i'
substring
substring2
更新:
如果您的输入是一个 xml 文件,您可能想要这样做:
<archive>
<message id="0">
<receiver>apr</receiver>
<sender>gtr</sender>
<text>52333</text>
<sendTime>554</sendTime>
<deliveryTime>765</deliveryTime>
</message>
<message id="0">
<receiver>apr</receiver>
<sender>gtr</sender>
<text>4332</text>
<sendTime>764</sendTime>
<deliveryTime>922</deliveryTime>
</message>
</archive>"
通向 cmd :
xmlstarlet sel -t -m '//message' -v receiver -o " " -v sender -o " " -v text -n <file>
哪个输出
apr gtr 52333
apr gtr 4332
【讨论】:
以上是关于如何使用 sed 一次提取标记之间的多个模式?的主要内容,如果未能解决你的问题,请参考以下文章