在mac上的bash中从xml中提取值

时间:2017-04-28 10:30:07

标签: regex xml bash grep

我需要从这个xml中提取名称值(Product Finder):

文件:config.xml

<?xml version="1.0" encoding="utf-8"?>
<widget id="com.abc.app" version="1.3.1" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0" ios-CFBundleVersion="1.3.1.5" android-versionCode="5">
    <name>Product Finder</name>
    <description>
        Description
    </description>
</widget>

我试过了:

mles$ cat config.xml | grep '<name>'
    <name>Product Finder</name>

其他一些答案建议使用grep -oPm1 "(?<=<xmltag>)[^<]+",但会产生错误:

mles$ cat config.xml | grep -oPm1 "(?<=<name>)[^<]+"
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
[-e pattern] [-f file] [--binary-files=value] [--color=when]
[--context[=num]] [--directories=action] [--label] [--line-buffered]
[--null] [pattern] [file ...]

如何获取名称值?我需要一个没有依赖关系的解决方案,因此grep将是首选

4 个答案:

答案 0 :(得分:3)

grep只找到该行,您必须使用其他工具来提取名称,例如sed(不是其他依赖项):

grep '<name>' config.xml | sed "s@.*<name>\(.*\)</name>.*@\1@"

此处sed的作用是<name></name>之间的所有内容,并用标记之间找到的文字替换整行

答案 1 :(得分:1)

您应该使用xml解析器,例如xmllint 您的 xml无效,您应该修复它,如果不能,请使用以下正则表达式:

/^(.*hello.*){/*amount to catch here*/}$/g

选项:

perl -n -e'/<name>(.*)<\/name>/ && print $1' file.xml
# Product Finder

答案 2 :(得分:1)

您的<?xml version="1.0" encoding="utf-8"?>在语法上是不对的。 W3School XML validitor页面是这样说的,

  第8行第1页的

错误。文档末尾的额外内容

由于标题行XMLprocessing instruction,因此将文档标识为XML。所有XML文档都应以xmllint声明开头。

此外,Mac OS X默认情况下应该内置到原生xmllint --xpath "/widget/name/text()" xml Product Finder bash中,您可以这样做

XML

<?xml version="1.0" encoding="UTF-8"?> <widget id="123" version="1.3.1"> <name>Product Finder</name> <description>Description</description> </widget> 的正确格式应该是

No provider for NameService

答案 3 :(得分:1)

以下bash内置功能可以完成这项任务,但它不是一个xml解析器

while IFS=\> read -d\< -r tag value || [[ -n $tag ]]; do
    if [[ $tag == name ]]; then
        echo "$value";
        break;
    fi;
done < config.xml