2017-02-09 95 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