如何使用bash脚本从标记之间提取文件文本

时间:2011-02-01 08:05:54

标签: bash unix scripting

我正在阅读这个问题: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”才能到达这一行,因为可能有类似的值其他行中的字段,该标签的值是我想要的。

4 个答案:

答案 0 :(得分:3)

如果它们在同一条线上(就像它们似乎来自你的例子),那就更容易了。只是:

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

说明:

  • -n:禁止默认打印
  • / name =“GUI \ / LastVMSelected”/:仅匹配此模式的行
  • S / 值= “([^”])”。 / \ 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