我已经使用grep从源文档中提取了标记,但现在我似乎无法弄清楚如何从字符串中轻松提取属性。另外,我想避免使用标准安装中通常不会出现的任何程序。
$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"
答案 0 :(得分:4)
您可以使用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 """ -v $2 -o """
}
$ src=get_attribute $tag '//img/@src'
如果您不想多次重新分析文档,也可以执行以下操作:
$ get_values() {
eval file=\${$#}
eval $#=
cmd="xmlstarlet sel "
for arg in $@
do
if [ -n $arg ]
then
var=${arg%%\=*}
expr=${arg#*=}
cmd+=" -t -o \"$var="\" -v $expr -o \""\" -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函数的最后一个参数,但我不知道。
答案 1 :(得分:1)
我选择了dacracot建议使用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/'`
答案 2 :(得分:0)
如果xmlstarlet在标准安装中可用且src-title-alt的顺序没有改变,您也可以使用以下代码:
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"
答案 3 :(得分:0)
由于这再次冒出来,现在我的Xidel有2个功能使这个任务变得微不足道:
xml上的模式匹配
将所有匹配的变量导出到shell
所以它变成了一行:
eval $(xidel "$tag" -e '<img src="{$src}" title="{$title}" alt="{$alt}"/>' --output-format bash)