1

我正在尝试编写一个 shell 脚本,它将一组名称/值对和一个 XML 文件作为输入。

目的是在 XML 文件中从名称/值对文件(用标签划分)中搜索“名称”字符串,并替换在 XML 文件的同一级别定义的“值”字符串(用标签划分)。

例如

名称/值对文件

trousers=blue
hat=red
shoes=brown

输入 XML 文件

<application>
    <Pairs>
        <Pair>
            <name>trousers</name>
            <value>black</value>
        </Pair>
        <IrritatingExtraLayer>
            <Pair>
                <name>hat</name>
                <value>green</value>
            </Pair>
        </IrritatingExtraLayer>
        <Pair>
            <name>shirt</name>
            <value>orange</value>
        </Pair>
    </Pairs>
</application>

预期的输出文件

<application>
    <Pairs>
        <Pair>
            <name>trousers</name>
            <value>blue</value>
        </Pair>
        <IrritatingExtraLayer>
            <Pair>
                <name>hat</name>
                <value>red</value>
            </Pair>
        </IrritatingExtraLayer>
        <Pair>
            <name>shirt</name>
            <value>orange</value>
        </Pair>
    </Pairs>
</application>

我已经创建了一个可以使用 xmlstarlet 执行此操作的脚本,但是它非常慢(我正在使用的文件长达数千行)。我的脚本中的主要代码片段(忽略预处理和后处理)是:

for line in ${namevaluepairs}; do
                name=$(echo ${line} | cut -d'=' -f1)
                value=$(echo ${line} | cut -d'=' -f2)

                outputxml=$(echo ${outputxml} | xmlstarlet ed -u "//Pair/[name='${name}']/value" -v "${value}" )
done

我能做些什么来改善这一点?

4

1 回答 1

1

我通常使用xsh来完成类似的任务。我会对以下与 xmlstarlet 相比有多快感兴趣。

perl { 
    open $FH, '<', 'namevalues' or die $!;
    while (<$FH>) {
        chomp;
        ($n, $v) = split /=/;
        $h->{$n} = $v;
    }
} ;
open 1.xml ;
for //name {
    $v = xsh:lookup('h', text()) ;
    if $v set ../value $v ;
}
save :b ;

诀窍是将名称-值对存储在散列(映射、字典)中,然后处理所有名称并从散列中检索相应的值。

于 2014-04-02T19:26:51.877 回答