извлекать строки из ответа сервиса и групповых значений на основе ключей из этого ответа - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть служба (http://localhost:8080/tester), которая выдает мне ответ ниже, когда я звоню.Я сократил формат, чтобы прояснить его.

modified=false
ver=10
PATH=/doc/path/abc
    Servers:3
    pri:{0=1, 1=2, 2=3, 3=4, 4=5, 5=6, 6=7, 7=8, 8=1, 9=2, 10=3, 11=4, 12=5, 13=6, 14=7, 15=8, 17=2, 16=1, 19=4, 18=3, 21=6, 20=5, 23=8, 22=7, 25=2, 24=1, 27=4, 26=3, 29=6, 28=5, 31=8, 30=7, 34=3, 35=4, 32=1, 33=2, 38=7, 39=8, 36=5, 37=6, 42=3, 43=4, 40=1}
    sec:{0=2, 1=3, 2=4, 3=5, 4=6, 5=7, 6=8, 7=1, 8=3, 9=4, 10=5}
PATH=/doc/path/pqr
    Servers:3
    pri:{0=1, 1=2, 2=3, 3=4, 4=5, 5=6, 6=7, 7=8, 8=1, 9=2, 10=3, 11=4, 12=5, 13=6, 14=7, 15=8, 17=2, 16=1, 19=4, 18=3, 21=6, 20=5, 23=8, 22=7, 25=2, 24=1, 27=4, 26=3, 29=6, 28=5, 31=8, 30=7, 34=3, 35=4, 32=1, 33=2, 38=7, 39=8, 36=5, 37=6, 42=3, 43=4, 40=1}
    sec:{0=2, 1=3, 2=4, 3=5, 4=6, 5=7, 6=8, 7=1, 8=3, 9=4, 10=5}

Мне нужно прочитать этот ответ и извлечь значения pri и sec, но только для PATH=/doc/path/abc.Теперь формат pri и sec выглядит следующим образом:

{value1=key1, value2=key2, value3=key2, value4=key1}

Каждый уникальный ключ может иметь несколько значений как в списке pri, так и sec.Теперь мне нужно прочитать список pri и sec и сделать два файла p.txt для списка pri и s.txt для sec списка путем группировки значений на основе уникального ключа, как показано ниже:

p.txt Здесь ключи и значения поступают из списка pri.

{key1=[value1, value2, value3, value4, value5, value6, value7, value8], key2=[value9, value10, value11, value12, value13, value14]}

s.txt Здесь ключи и значения поступают из списка sec.

{key1=[value1, value2, value3, value4, value5, value6, value7, value8], key2=[value9, value10, value11, value12, value13, value14]}

Я не могу понять, как извлечь значение pri и sec только для PATH=/doc/path/abc и сделать соответствующие файлы p.txt и s.txt, просто сгруппировав значения для каждого уникального ключакак в вышеуказанном формате.

DATA=$(wget -O - -q -t 1 http://localhost:8080/tester);
echo $DATA
# extract pri and sec here and then group values basis on unique keys 
# and generate files accordingly.
while IFS= read -r $DATA
do
   echo "$line"
done

1 Ответ

0 голосов
/ 26 апреля 2018

Хорошо, мой Perl немного ржавый, но вот кое-что, с чего можно начать.Он анализирует всю структуру данных, а затем извлекает части, указанные в командной строке.Я не знаю, с какой версией Perl вы работаете, или если у вас есть возможность устанавливать модули, поэтому я сохранил ее как можно проще.

#!/usr/bin/perl

use strict;
use warnings;

unless (@ARGV >= 2) {
  die "USAGE: $0 path key=/path/to/key.txt ..\n";
}

our $WANTED_PATH = $ARGV[0];
our %WANTED_KEYS = map split(/=/, $_, 2), @ARGV[1..$#ARGV];

my $data = parse(*STDIN)->{PATH}{$WANTED_PATH}
  or die "FATAL: Path <$WANTED_PATH> not found\n";

while (my ($key, $file) = each %WANTED_KEYS) {
  unless (exists $data->{$key}) {
    warn "Key <$key> not found\n";

    next;
  }

  write_file($file, $data->{$key});

  print "Wrote key <$key> to file <$file>\n";
}

sub parse {
  my ($fh, $wanted) = @_;

  # contains the current subsection of the data being parsed
  my $current_path;

  my %data = (PATH => {});
  while (my $line = <$fh>) {
    chomp $line;

    next unless $line =~ /\S/;

    if ($line =~ s/^\s+//) {
      if ($current_path) {
        my ($key, $value) = split /\s*:\s*/, $line, 2;

        if (exists $WANTED_KEYS{$key}) {
          $value = parse_pairs($value);
        }

        $data{PATH}{$current_path}{$key} = $value;
      }
    }
    else {
      my ($key, $value) = split /\s*=\s*/, $line, 2;

      if ($key eq 'PATH') {
        $data{$key}{$current_path = $value} = {};
      }
      else {
        $data{$key} = $value;
      }
    }
  }

  return \%data;
}

sub parse_pairs {
  my ($pairs) = @_;

  my %data;
  while ($pairs =~ /(\d+)\s*=\s*(\d+)/g) {
    push @{ $data{$2} ||= [] }, $1;
  }

  return \%data;
}

sub write_file {
  my ($file, $data) = @_;

  open(my $fh, '>', $file)
    or die "FATAL: Unable to open file <$file> for writing: $!\n";

  print {$fh} '{';
  print {$fh} join ', ',
    map sprintf('%s=[%s]', $_, join(', ', sort @{ $data->{$_} })),
    sort keys %$data;
  print {$fh} '}';

  close($fh);
}

Используйте это так:

wget -O- -q -t1 http://localhost:8080/tester |
  ./tester.pl /doc/path/abc pri=p.txt sec=s.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...