Как найти максимальное значение из определенного элемента XML с помощью однострочной строки Perl?

awkрешение длялюбоеколичество столбцов (вы упомянули образец файла с 13 столбцами):

Допустим, у нас есть файл расширенного примера:

1   10  15  10  99
3   34  20  20  111
1   4   22  22  33
3   32  33  12  5
5   3   46  44  9
2   2   98  55  55 
4   20  100 11  33
3   13  23  77  23
4   50  65  33  66
1   40  76  78  16
2   20  22  98  93

awk '{ for(i=2;i<=NF;i++) { if (!($1 in a) || $i > a[$1][i]) a[$1][i]=$i }}
     END{ r=""; for(i in a) { r=i; for(j in a[i]) r=r OFS a[i][j]; print r } 
     }' OFS='\t' file

Выход:

1   40  76  78  99
2   20  98  98  93
3   34  33  77  111
4   50  100 33  66
5   3   46  44  9
1
25.09.2019, 15:07
1 ответ

Автономный perl-скрипт:

#!/usr/bin/perl

use strict;
use XML::LibXML;
use List::Util qw(max);

my $filename = './input.xml';
my $dom = XML::LibXML->load_xml(location => $filename);

my @ids = map { $_->to_literal() } $dom->findnodes('/data/element/id');

print max(@ids), "\n";

Уродливее, сложнее -для -понимания и сложнее -для -редактирования одной -версии вкладыша:

perl -MXML::LibXML -MList::Util=max -e '
  $dom = XML::LibXML->load_xml(location => shift);
  @ids = map { $_->to_literal() } $dom->findnodes("/data/element/id");
  print max(@ids), "\n";' input.xml

Обратите внимание, :оба вышеперечисленных варианта предполагают, что <element>s заключены в путь <data>. Если нет, настройте xpath в вызове функции findnodes()в соответствии с вашими фактическими данными.

Я запустил их оба со следующим input.xmlфайлом:

<?xml version='1.0' encoding='UTF-8'?>
<data>
<element>
  <id>0</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>1</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>2</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>3</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>4</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>5</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
</data>

и оба получили правильный результат 5.


Кстати, любую версию можно заставить читать STDIN, изменив строки с location => $filenameили location => shiftна:

my $dom = XML::LibXML->load_xml(IO => *STDIN);

myявляется необязательным в версии с одним вкладышем -без use strict, но требуется в версии с одной подставкой -.


Кстати, любой сценарий также легко изменить, чтобы в командной строке можно было указать и имя входного файла, и xpath. чтобы у вас был общий инструмент для получения значения max()любого элемента xpath. например.

#!/usr/bin/perl

use strict;
use XML::LibXML;
use List::Util qw(max);

my $dom = XML::LibXML->load_xml(location => shift);
my @ids = map { $_->to_literal() } $dom->findnodes(shift);
print max(@ids), "\n";

Запустить как, например,

$ xml-max.pl input.xml /data/element/id
5
0
28.01.2020, 00:00

Теги

Похожие вопросы