Perl - находит различия в значениях внутри строки на многих хешах, у которых есть идентификатор в имени ключа - PullRequest
0 голосов
/ 26 апреля 2018

У меня много конфигурационных файлов с параметрами для внешней программы. Мой скрипт протестирует все эти конфиги печати в STDOUT и CSV. Но чтобы сделать этот интерфейс скрипта более читабельным, я бы напечатал имя файла и изменил параметры для каждого файла.

Вот примеры. Мой хэш хешей выглядит так:

$hoh{string 1}{conf} = 'SMA_long = 712 SMA_short = 38 decay = 0.0076 learning_rate = 0.27 min_predictions = 20 momentum = 0.09 price_buffer_len = 88 threshold_buy_bear = 2.5 threshold_buy_bull = 1.9 threshold_sell_bear = -0.6 threshold_sell_bull = -0.6';
$hoh{string 5}{conf} = 'SMA_long = 712 SMA_short = 38 decay = 0.0076 learning_rate = 0.27 min_predictions = 20 momentum = 0.09 price_buffer_len = 88 threshold_buy_bear = 2.5 threshold_buy_bull = 2.1 threshold_sell_bear = -0.6 threshold_sell_bull = -0.6';
$hoh{string 8}{conf} = 'SMA_long = 712 SMA_short = 38 decay = 0.0076 learning_rate = 0.27 min_predictions = 20 momentum = 0.09 price_buffer_len = 88 threshold_buy_bear = 2.4 threshold_buy_bull = 2.1 threshold_sell_bear = -0.6 threshold_sell_bull = -0.7';
$hoh{another string 1}{conf} = 'threshold_buy_bear = 2.5 HNA_long = 712  aaaaa = 0.0076 ccccc = 0.27 bbbbbbb = 1.9 dedede = -0.6 threshold = -0.6';
$hoh{another string 2}{conf} = 'threshold_buy_bear = 2.5 HNA_long = 712  aaaaa = 0.0076 ccccc = 0.27 bbbbbbb = 2.1 dedede = -0.5 threshold = -0.6';
$hoh{another string 3}{conf} = 'threshold_buy_bear = 2.5 HNA_long = 712  aaaaa = 0.0076 ccccc = 0.27 bbbbbbb = 2.0 dedede = -0.6 threshold = -0.6';

И я бы хотел добиться такого результата, как использование следующих строк ...

$hoh{string 1}{values} = '2.5 1.9 -0.6';
$hoh{string 5}{values} = '2.5 2.1 -0.6';
$hoh{string 8}{values} = '2.4 2.1 -0.7';
$hoh{another string 1}{values} = '1.9 -0.6';
$hoh{another string 2}{values} = '2.1 -0.5';
$hoh{another string 3}{values} = '2.0 -0.6';

Таким образом, мой вывод скрипта будет генерировать STDOUT что-то вроде этого:

test of string 1 with values 2.5 1.9 -0.6
test of string 5 with values 2.5 2.1 -0.6
test of string 8 with values 2.4 2.1 -0.7
test of another string 1 with values 1.9 -0.6
test of another string 2 with values 2.1 -0.5
test of another string 3 with values  2.0 -0.6

... с той разницей, что я бы хотел, чтобы скрипт искал значения, которые меняются для меня.

Более длительный срок годности: Я хотел бы сохранить эти данные в хэше хэшей, а затем найти значения, которые меняются хотя бы один раз из заданной «строки» или «другой строки», и назначить их ключу значения в данном хэше хэшей. Ключ представляет собой строку и случайное число. Сценарий должен сравнивать только значения хеш-функции, в которых строка идентична (как если бы вы вырезали все цифры из ключей), то есть значение ключа {строка}! = {Другая строка} и {строка 1} = {строка 2}. Подчеркиваю, что значения хешей {config} очень переменны. Обычно /(threshold_buy_bull = )\d+/ недостаточно.

Ответы [ 2 ]

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

ОК, поэтому, во-первых, я бы сказал, что хранение ваших данных в подстроках - неправильный способ сделать это. Разложите их на пары ключ-значение:

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

my %hoh; 

$hoh{"string 1"}{conf} = 'SMA_long = 712 SMA_short = 38 decay = 0.0076 learning_rate = 0.27 min_predictions = 20 momentum = 0.09 price_buffer_len = 88 threshold_buy_bear = 2.5 threshold_buy_bull = 1.9 threshold_sell_bear = -0.6 threshold_sell_bull = -0.6';
$hoh{"string 5"}{conf} = 'SMA_long = 712 SMA_short = 38 decay = 0.0076 learning_rate = 0.27 min_predictions = 20 momentum = 0.09 price_buffer_len = 88 threshold_buy_bear = 2.5 threshold_buy_bull = 2.1 threshold_sell_bear = -0.6 threshold_sell_bull = -0.6';
$hoh{"string 8"}{conf} = 'SMA_long = 712 SMA_short = 38 decay = 0.0076 learning_rate = 0.27 min_predictions = 20 momentum = 0.09 price_buffer_len = 88 threshold_buy_bear = 2.4 threshold_buy_bull = 2.1 threshold_sell_bear = -0.6 threshold_sell_bull = -0.7';
$hoh{"another string 1"}{conf} = 'threshold_buy_bear = 2.5 HNA_long = 712  aaaaa = 0.0076 ccccc = 0.27 bbbbbbb = 1.9 dedede = -0.6 threshold = -0.6';
$hoh{"another string 2"}{conf} = 'threshold_buy_bear = 2.5 HNA_long = 712  aaaaa = 0.0076 ccccc = 0.27 bbbbbbb = 2.1 dedede = -0.5 threshold = -0.6';
$hoh{"another string 3"}{conf} = 'threshold_buy_bear = 2.5 HNA_long = 712  aaaaa = 0.0076 ccccc = 0.27 bbbbbbb = 2.0 dedede = -0.6 threshold = -0.6';

print Dumper \%hoh;

foreach my $conf ( values %hoh ) { 
   print $conf -> {conf};
   $conf = { map { /(\w+) = ([\d\.\-]+)/g } $conf -> {conf} };
}

print Dumper \%hoh;

Таким образом, вы получите %hoh:

$VAR1 = {
          'another string 2' => {
                                  'threshold' => '-0.6',
                                  'ccccc' => '0.27',
                                  'bbbbbbb' => '2.1',
                                  'dedede' => '-0.5',
                                  'threshold_buy_bear' => '2.5',
                                  'HNA_long' => '712',
                                  'aaaaa' => '0.0076'
                                },

... и т. Д.

Теперь я не могу сказать, откуда берутся ваши "значения" во втором примере, но, надеюсь, будет намного проще сравнивать.

Вы можете получить 3 значения, которые я думаю вы ищете:

foreach my $key ( keys %hoh ) { 
   print $key, " => ", $hoh{$key}{threshold_buy_bear},"\n";
}

Или просто сделайте это с ломтиком хеша:

my @values = qw ( threshold_buy_bear threshold_buy_bull threshold_sell_bull );

foreach my $key ( sort keys %hoh ) { 
   print $key, " => ", join ( " ", @{$hoh{$key}}{@values} ), "\n";
}
0 голосов
/ 26 апреля 2018

Если это не должно быть одно-единственное выражение, например,

my $temp = '';
while ($hoh{$hashkey}{conf} =~ m/(\S+)\s*=\s*(\S+)/gc) {
  my ($key, $value) = ($1, $2);
  # replace the condition of the if by anything you need;
  # it's just an example on top of the OP's example
  if ($key =~ m/^threshold/) {
    $temp .= ((length($temp) ? ' ' : '') . $value);
  }
}
$hoh{$hashkey}{values} = $temp;

для каждой клавиши $hashkey может подойти? Каждая итерация цикла while будет обрабатывать одно совпадение. Значения сопоставленной пары ключ-значение объединяются во временную строку, которая затем присваивается хешу.

...