从服务响应中提取字符串,并根据该响应中的键对值进行分组

2024-05-29 02:38:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个服务(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}

我需要阅读这个响应并提取prisec的值,但只针对PATH=/doc/path/abc。现在prisec的格式如下:

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

每个唯一键在prisec列表中都可以有多个值。现在我需要同时读取prisec列表,并通过基于如下唯一键对值进行分组,为pri列表和s.txt列表创建两个文件p.txt

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]}

我不知道如何提取prisec值只为PATH=/doc/path/abc和相应的文件p.txts.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

Tags: pathtxt列表doc格式secpriabc
1条回答
网友
1楼 · 发布于 2024-05-29 02:38:32

嗯,我的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

相关问题 更多 >

    热门问题