2008-10-09 74 views
2

我已经使用grep从源文档中提取标签,但现在我似乎无法弄清楚如何轻松地从字符串中提取属性。另外我想避免使用任何通常不会出现在标准安装中的程序。如何使用shell脚本提取xml属性?

$tag='<img src="http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg" title="Don't we all." alt="Barrel - Part 1" />' 

我需要以下变量

$src="http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg" 
$title="Don't we all." 
$alt="Barrel - Part 1" 

回答

1

我的使用sed的,虽然他给了我一些示例代码

src=`echo $tag | sed 's/.*src=["]\(.*\)["] title=["]\(.*\)["] alt=["]\(.*\)["].*/\1/'`  
title=`echo $tag | sed 's/.*src=["]\(.*\)["] title=["]\(.*\)["] alt=["]\(.*\)["].*/\2/'` 
alt=`echo $tag | sed 's/.*src=["]\(.*\)["] title=["]\(.*\)["] alt=["]\(.*\)["].*/\3/'` 
+1

使用SED是一个非常,非常糟糕的做法 - 这是脆,不知道任何关于XML标准,当遇到像&amp; amp;这样的东西时,会给你带来不好的结果。见Torsten Marek的建议。 – 2008-10-10 02:34:48

+0

对不起,我没有为你制定sed脚本,我没有时间吧 – dacracot 2008-10-10 04:19:00

4
我会者优先dacracot的建议去结束

您可以使用xmlstarlet。然后,你甚至不必提取元素自己:

$ echo $tag|xmlstarlet sel -t --value-of '//img/@src' 
http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg 

你甚至可以变成一个功能

$ get_attribute() { 
    echo $1 | xmlstarlet sel -t -o "&quot;" -v $2 -o "&quot;" 
    } 
$ src=get_attribute $tag '//img/@src' 

这个,如果你不想多次重新分析文档,你也可以这样做:

$ get_values() { 
    eval file=\${$#} 
    eval $#=  
    cmd="xmlstarlet sel " 
    for arg in [email protected] 
    do 
     if [ -n $arg ] 
     then 
     var=${arg%%\=*} 
     expr=${arg#*=} 
     cmd+=" -t -o \"$var=&quot;\" -v $expr -o \"&quot;\" -n" 
     fi 
    done 
    eval $cmd $file 
    } 
$ eval $(get_values src='//img/@src' title='//img/@title' your_file.xml) 
$ echo $src 
http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg 
$ echo $title 
Don't we all. 

我敢肯定有一个更好的方法来删除shell函数的最后一个参数,但我不知道它。

0

如果xmlstarlet可在一个标准的安装和SRC-冠军中高音的顺序不会改变,你可以使用下面的代码,以及:

tag='<img src="http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg" title="Don'"'"'t we all." alt="Barrel - Part 1" />' 
xmlstarlet sel -T -t -m "/img" -m "@*" -v '.' -n <<< "$tag" 
IFS=$'\n' 
array=($(xmlstarlet sel -T -t -m "/img" -m "@*" -v '.' -n <<< "$tag")) 
src="${array[0]}" 
title="${array[1]}" 
alt="${array[2]}" 

printf "%s\n" "src: $src" "title: $title" "alt: $alt" 
0

由于这再次向上冒泡,现在有我Xidel有2个功能,使这个任务变得简单:

  • 模式上的XML

  • 导出所有匹配匹配变量外壳

所以就变成了单行:

eval $(xidel "$tag" -e '<img src="{$src}" title="{$title}" alt="{$alt}"/>' --output-format bash)