I'm trying to write a shell script which will take, as input, a set of name/value pairs and an XML file.
The aim is to search within the XML file for the "name" string from the name/value pairs file (demarcated with tags), and replace the "value" string defined at the same level of the XML file (demarcated with tags).
eg
Name/value pairs file
trousers=blue
hat=red
shoes=brown
Input XML file
<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>
Expected output file
<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>
I have already created a script which can do this using xmlstarlet, however it is very slow (the files I am working with are thousands of lines long). The main code snippet (ignoring pre-processing and post-processing) from my script is:
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
What can I do to improve this?
I usually use xsh for similar tasks. I would be interested how fast the following compared to the 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 ;
The trick is to store the name-value pairs in a hash (map, dictionary), then process all the names and retrieve the corresponding values from the hash.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.