2011-02-01 43 views
1

我正在阅读此问题:Extract lines between 2 tokens in a text file using bash ,因为我有一个非常类似的问题... 我必须提取(并保存到$变量打印前)文本此XML文件:如何从使用bash脚本的令牌之间的文件文本中提取

<--more labels up this line> 
<ExtraDataItem name="GUI/LastVMSelected" value="14cd3204-4774-46b8-be89-cc834efcba89"/> 
<--more labels and text down this line--> 

我只需要获得价值=(显然没有支架,没有“价值=”),但首先,我想这要搜索“GUI/LastVMSelected”得到这条线,因为在其他行中可能有类似的值字段,并且该标签的值是我想要的。

+1

如果这是一个xml/html,你应该考虑使用一个合适的xml解析器 – ajreal 2011-02-01 08:13:20

回答

2

如果他们在同一行(如他们似乎从你的例子),它更容易。刚:

sed -ne '/name="GUI\/LastVMSelected"/s/.*value="\([^"]*\)".*/\1/p' 

说明:

  • -n:禁止默认打印
  • /NAME = “GUI \/LastVMSelected”/:仅此模式匹配的
  • 秒/线。 value =“([^”])“。/\ 1/P
    • 代替一切,捕获括号的部分(价值值)
    • 和打印结果
1

我假设你是从一个XML文档中提取的。如果是这种情况,请查看用于处理XML的XMLStarlet命令行工具。有一些查询XML文档的文档here

1

使用此:

for f in `grep "GUI/LastVMSelected" filename.txt | cut -d " " -f3`; do echo ${f:7:36}; done 
  • grep让你只需要
  • cut线条分割使用一些分离器的线,并返回分割
  • -d " "的第N个结果集的分离器到空间
  • -f3返回第三个结果(基于1的索引)
  • ${f:7:36}提取从索引7开始的长度为36个字符的子字符串。这摆脱了领先value="和斜线的,等

显然,如果领域变化的顺序,这将打破,但如果你只是一些快速和肮脏的作品后是,这应该是它。

+0

这不会去掉value和quotes。 – 2011-02-01 08:18:55

+0

谢谢。看我的编辑。 – misha 2011-02-01 08:24:59

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 - 标签 “一”
      • n - 读取下一行
      • /<!-- this is token 2 -->/q - 如果它是结束标记,退出
      • \|GUI/LastVMSelected| - 如果行匹配字符串
        • s/value="\([^"]*\)"/\1/p - 打印字符串后 '值=' 和下一个引号之前
    • ba - 分支标记 “一”
  • }末如果
相关问题