Below is an excerpt from some xml files that need processing:
<BirimAdi>Adet</BirimAdi>
<BirimCarpan>1</BirimCarpan>
<HavaleFiyati>0</HavaleFiyati>
<HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi>
<Price1>0</Price1>
<SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi>
<Isk1>0</Isk1>
<SatisFiyati2>0</SatisFiyati2>
What I need to do is take the value between tags and do the following mathematical operation on it.
Price1 = round(Price1)-0.1;
The script should do it to all xml files in a specified path.
I have considered using 'sed' or 'awk' but I am not sure this can be done easily in sed. Using xmllint looked too much of an overkill to me. Any ideas? I am new to these utilities so couldn't figure much expect that the regex that will find the bit I am looking for is:
/<\s*Price1[^>]*>([^<]*)<\s*\/\s*Price1\s*>/
I would use a XML
parser for the job. For example, XML::Twig
. Here an example:
#!/usr/bin/env perl
use warnings;
use strict;
use XML::Twig;
for my $f ( @ARGV ) {
my $twig = XML::Twig->new(
twig_handlers => {
'Price1' => sub { $_->set_text( sprintf( "%.1f", int( $_->text) - 0.1 ) ) },
},
pretty_print => 'indented',
)->parsefile( $f )->print;
}
Assuming file name is script.pl
and a test file xmlfile
with content:
<root>
<BirimAdi>Adet</BirimAdi>
<BirimCarpan>1</BirimCarpan>
<HavaleFiyati>0</HavaleFiyati>
<HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi>
<Price1>3.3</Price1>
<SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi>
<Isk1>0</Isk1>
<SatisFiyati2>0</SatisFiyati2>
</root>
Run it like:
perl script.pl xmlfile
That yields:
<root>
<BirimAdi>Adet</BirimAdi>
<BirimCarpan>1</BirimCarpan>
<HavaleFiyati>0</HavaleFiyati>
<HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi>
<Price1>2.9</Price1>
<SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi>
<Isk1>0</Isk1>
<SatisFiyati2>0</SatisFiyati2>
</root>
A quick a dirty solution:
perl -pe 's!<(Price1)>(\d+(?:\.\d*)?)</\1>!"<$1>".(int($2+0.5)-0.1)."</$1>"!e'<<XXX
<HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi>
<Price1>2.3</Price1>
<SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi>
<Price1>2.5</Price1>
XXX
Output:
<HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi>
<Price1>1.9</Price1>
<SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi>
<Price1>2.9</Price1>
But Birei's solution is better by far...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With