0

我在一个非常大的文件中有以下 xml 结构:

<sit>619709.6044;144998.7059;-090372.58119</sit>
<vll>0;0;0</vll>
<cor>255;0;255</cor>

如何减去标签中的值?该标签由三个值组成,由;分隔。每个都必须从特定数字中减去。

可以使用任何 unix 工具。(awk、sed、bc 等)

因此,如果该特定数字对于第一个值是 1000,对于第二个值是 100,对于第三个值是 10,则结果将是:

<sit>618709;144898;-090362</sit>
<vll>0;0;0</vll>
<cor>255;0;255</cor>

无需保留分数。

4

3 回答 3

2
awk '
BEGIN{ split("1000 100 10",dec); FS=OFS=";" }
gsub(/<\/?sit>/,"") {
   for (i=1;i<=NF;i++)
      $i = int($i - dec[i])
   $0="<sit>" $0 "</sit>"
}
1' file
<sit>618709;144898;-90382</sit>
<vll>0;0;0</vll>
<cor>255;0;255</cor>
于 2013-02-09T00:50:49.580 回答
2

这是使用awk. 像这样运行:

awk -v a=1000 -v b=100 -v c=10 -F "[<;>]" -v OFS=";" -f ./script.awk file

内容script.awk

/^<sit>/ && /<\/sit>$/ {
    $0 = "<sit>" format($3, a) OFS format($4, b) OFS format($5, c) "</sit>"
}1

function format(field, var) {
    f = sub(/^-/, "", field)
    return (f == 1 ? "-" : "") sprintf("%06d", int(field-var))
}

结果:

<sit>618709;144898;-090362</sit>
<vll>0;0;0</vll>
<cor>255;0;255</cor>

您还没有完全清楚如何格式化输出。看起来您希望您的整数最多填充六个前导零,无论它们是正数还是负数。上面的脚本会做到这一点。如果那个零实际上是一个错字,那么这个单行就足够了:

awk -v a=1000 -v b=100 -v c=10 -F "[<;>]" -v OFS=";" '/^<sit>/ && /<\/sit>$/ { $0 = "<sit>" sprintf("%06d",int($3-a)) OFS sprintf("%06d",int($4-b)) OFS sprintf("%06d",int($5-c)) "</sit>" }1' file

结果:

<sit>618709;144898;-90382</sit>
<vll>0;0;0</vll>
<cor>255;0;255</cor>
于 2013-02-09T01:37:28.147 回答
1

在解析器perl的帮助下使用的一种方法:XML::Twig

假设xmlfile有以下数据:

<root>
        <sit>619709.6044;144998.7059;-090372.58119</sit>
        <vll>0;0;0</vll>
        <cor>255;0;255</cor>
</root>

和代码script.pl

#!/usr/bin/env perl

use warnings;
use strict;
use XML::Twig;
use POSIX qw<floor ceil>;

my @substracts = qw<1000 100 10>;

my $twig = XML::Twig->new(
    twig_handlers => {
        'sit' => sub { 
            my @sit_values = map { $_ < 0 ? ceil $_ : floor $_  } split /;/, $_->text_only;
            for my $i ( 0 .. $#substracts ) { 
                $sit_values[ $i ] -= $substracts[ $i ];
            }   

            $_->set_text( join q|;|, @sit_values );
        }   
    },  
    pretty_print => 'indented',
)->parsefile( shift )->print;

像这样运行它:

perl-5.14.2 script.pl xmlfile

这会产生:

<root>
  <sit>618709;144898;-90382</sit>
  <vll>0;0;0</vll>
  <cor>255;0;255</cor>
</root>
于 2013-02-08T23:10:04.583 回答