2017-02-09 94 views
0

XML文件:提取物領域文件

<head> 
    <head2> 
    <dict type="abc" file="/path/to/file1"></dict> 
    <dict type="xyz" file="/path/to/file2"></dict> 
    </head2> 
</head> 

我需要提取此文件列表。所以輸出將是

/path/to/file1 
/path/to/file2 

到目前爲止,我設法以下。

grep "<dict*file=" /path/to/xml.file | awk '{print $3}' | awk -F= '{print $NF}' 
+2

你可以用'xmllint'或'xmlstarlet'? 'awk/sed/grep'不是處理xml的正確工具 – Inian

+0

'xmllint'很好 – CR7

回答

1

快速並根據您的樣品骯髒的,而不是XML possibilties

# sed a bit secure 
sed -e '/<head>/,/<\/head>/!d' -e '/.*[[:blank:]]file="\([^"]*\)".*/!d' -e 's//\1/' YourFile 

# sed in brute force 
sed -n 's/.*[[:blank:]]file="\([^"]*\)".*/\1/p' -e 's//\1/' YourFile 



# awk quick unsecure using your sample 
awk -F 'file="|">' '/<head>/{h=1} /\/head>{h=0} h && /[[:blank:]]file/ { print $2 }' YourFile 
現在

,我不提倡這種提取物對XML除非真的知道如何在格式和內容源(額外字段,躲過報價,喜歡的標籤格式字符串的內容,...)是失敗和意想不到的結果,並沒有更多的適當的工具的一大原因是可用

現在使用自己的腳本

#grep "<dict*file=" /path/to/xml.file | awk '{print $3}' | awk -F= '{print $NF}' 
awk '! /<dict.*file=/ {next} {$0=$3;FS="\"";$0=$0;print $2;FS=OFS}' YourFile 
  • 沒有必要使用awk grep指令的用途,開始圖形過濾/<dict.*file/
  • 使用不同的分隔符(FS)第二AWK可以在同一個腳本改變FS內,但因爲它只發生在接下來的評測中進行(默認爲下一行),你可能會迫使當前內容以$ 0 = $ 0重新評估在這種情況下
1

使用的xmllint溶液-xpath//head/head2/dict/@file

xmllint --xpath "//head/head2/dict/@file" input-xml | awk 'BEGIN{FS="file="}{printf "%s\n%s\n", gensub(/"/,"","g",$2), gensub(/"/,"","g",$3)}' 
/path/to/file1 
/path/to/file2 

遺憾的是未能提供一個純粹的xmllint邏輯,因爲思想運用,

xmllint --xpath "string(//head/head2/dict/@file)" input-xml 

將兩個節點返回file屬性,但它僅返回第一個實例。

所以加入耦合我的邏輯與GNU Awk,以提取所需的值,這樣做

xmllint --xpath "//head/head2/dict/@file" input-xml 

返回值作爲

file="/path/to/file1" file="/path/to/file2" 

在上面的輸出,設置一個字符串去限制器file=和刪除使用gensub()函數的雙引號解決了這一要求。

1

另外PE [p ERL Ë verywhere :)]溶液:

perl -MXML::LibXML -E 'say $_->to_literal for XML::LibXML->load_xml(location=>q{file.xml})->findnodes(q{/head/head2/dict/@file})' 

它打印

/path/to/file1 
/path/to/file2 

對於上面的需要已經安裝了XML::LibXML模塊。

1

隨着xmlstarlet這將是:

xmlstarlet sel -t -v "//head/head2/dict/@file" -nl input.xml 
0

此命令:

awk -F'[=" ">]' '{print $12}' file 

威爾生產:

/path/to/file1 
/path/to/file2