2011-02-01 42 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 - 分支標記 「一」
  • }末如果
相關問題