我正在阅读这个问题:Extract lines between 2 tokens in a text file using bash 因为我有一个非常相似的问题...... 我必须在此xml文件中提取(并在打印前将其保存为$ variable)文本:
<--more labels up this line>
<ExtraDataItem name="GUI/LastVMSelected" value="14cd3204-4774-46b8-be89-cc834efcba89"/>
<--more labels and text down this line-->
我只需要得到值=(显然没有括号而没有'value ='),但首先,我认为它必须搜索“GUI / LastVMSelected”才能到达这一行,因为可能有类似的值其他行中的字段,该标签的值是我想要的。
答案 0 :(得分:3)
如果它们在同一条线上(就像它们似乎来自你的例子),那就更容易了。只是:
sed -ne '/name="GUI\/LastVMSelected"/s/.*value="\([^"]*\)".*/\1/p'
说明:
答案 1 :(得分:1)
我假设你是从XML文档中提取的。如果是这种情况,请查看用于处理XML的XMLStarlet命令行工具。有一些文档可用于查询XML文档here。
答案 2 :(得分:1)
使用此:
for f in `grep "GUI/LastVMSelected" filename.txt | cut -d " " -f3`; do echo ${f:7:36}; done
grep
只为您提供所需的行cut
使用某个分隔符拆分行,并返回拆分的第N个结果-d " "
将分隔符设置为空格-f3
返回第三个结果(从1开始索引)${f:7:36}
从索引7开始提取子字符串,长度为36个字符。这摆脱了领先的value="
和尾随斜杠等显然,如果字段的顺序发生变化,这将会中断,但如果你只是在做了一些快速而又脏的工作之后,就应该这样做了。
答案 3 :(得分:0)
使用我链接的问题的答案:
sed -n '/<!--more labels up this line-->/{:a;n;/<!--more labels and text down this line-->/b;\|GUI/LastVMSelected|s/value="\([^=]*\)"/\1/p;ba}' inputfile
说明:
-n
- 不要进行隐式打印/<!-- this is token 1 -->/{
- 如果找到了起始标记,那么
:a
- 标签“a”
n
- 阅读下一行/<!-- this is token 2 -->/q
- 如果它是结束标记,则退出\|GUI/LastVMSelected|
- 如果该行与该字符串匹配
s/value="\([^"]*\)"/\1/p
- 在'value ='之后和下一个引用之前打印字符串ba
- 分支以标记“a”}
if if