2017-02-14 31 views
-1

Мне нужно перенести скрипт PHP на Perl.IniFiles использует массив или hash

В моем PHP скрипт я разобрать INI файл с элементами массива в нем, как, например ...

[RADIUS] 
SRV[] = "server 1" 
SRV[] = "server 2" 
SRV[] = "server 3" 
... 
SRV[] = "server n" 

Это прекрасно работает в PHP, и мой вопрос, могу ли я использовать один и тот же файл INI в Perl или я должен переписать это следующим образом:

[RADIUS] 
SRV1 = "server 1" 
SRV2 = "server 2" 
SRV3 = "server 3" 
... 
SRV4 = "server n" 

Это неясно в CPAN.

Для первого варианта я могу пройти через хэш и прочитать мои значения с помощью цикла while или так, и мне не нужно заботиться, удаляю ли элемент, который соответствует нумерации.

Подсказка приветствуется! Заранее спасибо.

+0

Какой модуль у CPAN вы используете для этого? – simbabque

+0

Config :: IniFiles http://search.cpan.org/~shlomif/Config-IniFiles-2.94/lib/Config/IniFiles.pm –

+2

Пожалуйста, отредактируйте и покажите код, который вы написали, и что вы хотите сделать с вашей конфигурацией. Важно ли, чтобы эти серверные вещи оказались в массиве? Вам нужно, чтобы они были в порядке? – simbabque

ответ

0

Вот что я сделал работу для меня с помощью Config: IniFiles:

use Config::IniFiles; 
# Read Ini File 
my %MyCfg; 
tie %MyCfg, 'Config::IniFiles', (-file => "..".$MyPathSep."ini".$MyPathSep."file.ini"); 
foreach my $List1 (sort keys %{$MyCfg{'DataCenters'}}) { 
    if (ref $MyCfg{'DataCenters'}{$List1} eq 'ARRAY') { 
     foreach my $List2 (sort keys @{$MyCfg{'DataCenters'}{$List1}}) { 
      print $MyCfg{'DataCenters'}{$List1}[$List2]."\n"; 
     } 
    } else { 
     print $MyCfg{'DataCenters'}{$List1}."\n"; 
    } 
} 

Для секции ввода:

[DataCenters] 
; DC in location a 
LOCa[] = "DC1" 
LOCa[] = "DC2" 
LOCa[] = "DC3" 
LOCa[] = "DC4" 
; DC in location b 
LOCb[] = "DC5" 

Выход есть:

scripts\bin>perl switchcfg.pl 
    "DC1" 
    "DC2" 
    "DC3" 
    "DC4" 
    "DC5" 

Спасибо Вам за Ваш вклад! С уважением Laurent

0

Можно также прочитать файл строки за строкой и сохранить желаемые значения, если вы знакомы с немного регулярным выражением. Я использую это в моем примере ниже.

Если вам не нужен определенный порядок значений «сервер 1», «сервер 2» .., то вы можете использовать Hash, в противном случае - для массива.

Здесь, из вашего примера, тестовый образец файла:

%[email protected]> cat srv.txt 
SRV[] = "server 1" 
SRV[] = "server 2" 
SRV[] = "server 3" 
SRV[] = "server 109" 
SRV[] = "server 51" 
%[email protected]> 

Я прочитал его catting файл сценария, а затем сгенерировать хеш и массив, так как видел Data :: Dumper выход ниже.

%[email protected]> cat srv.txt |perl test.pl 

# Hash output [unordered] 
$VAR1 = '"server 109"'; 
$VAR2 = 1; 
$VAR3 = '"server 51"'; 
$VAR4 = 1; 
$VAR5 = '"server 1"'; 
$VAR6 = 1; 
$VAR7 = '"server 3"'; 
$VAR8 = 1; 
$VAR9 = '"server 2"'; 
$VAR10 = 1; 

# Array output [in order] 
$VAR1 = '"server 1"'; 
$VAR2 = '"server 2"'; 
$VAR3 = '"server 3"'; 
$VAR4 = '"server 109"'; 
$VAR5 = '"server 51"'; 
%[email protected]> 

Теперь у вас есть оба варианта, и вы можете действовать по своему усмотрению.

Это сценарий: Его логика такова: если строка соответствует «серверу», тогда обрабатывать и извлекать значения и сохранять в хэш-массиве и массиве, иначе пропустить.

#!/usr/bin/perl 

use strict; 
use warnings; 
use Data::Dumper ; 
my %hash ; 
my @array ; 

while (<>) 
{ 
    if (m/server/) { 
    if (m/^.+? = (.+)$/) { 
     $hash{$1} = 1 ; 
     push (@array, $1) ; 
    } 
    } 
} 

print Dumper %hash ; 
print Dumper @array ; 
+2

Зачем изобретать колесо, если для этого уже есть несколько модулей? – simbabque

+0

@simbabque: для оригинальности. :) – User9102d82

+0

Не изобретайте велосипед. Модули CPAN обычно имеют комплекты тестов для автоматизированных тестов и в большинстве случаев могут обрабатывать специальные случаи. Вы можете изобрести колесо самостоятельно, но, пожалуйста, не используйте его в качестве ответов здесь, когда есть модули CPAN. – dgw

1

Вы можете использовать свой ini-файл напрямую, но с некоторыми завихрениями.

Согласно docs:

вал ($ секции, $ параметра [, $ умолчанию])

Возвращает значение указанного параметра ($ параметров) в разделе $ раздела , возвращает undef (или $ default, если задано), если нет раздела или нет параметра для данного раздела.

Если вы хотите поле многострочного/значения возвращается в виде массива, просто задать массив в качестве приемника:

@values = $cfg->val('Section', 'Parameter'); 

многострочных/значение поля A, который возвращается в скалярном контексте будет соединен с использованием $/ (разделитель входных данных, по умолчанию - \ n), если он определен, иначе значения будут соединены с помощью \ n.

Следующая:

use 5.014; 
use warnings; 
use Config::IniFiles; 

use Data::Dumper; 

my $cfg = Config::IniFiles->new(-file => "./conf.ini"); 
my @v = $cfg->val('RADIUS', 'SRV[]'); 
say Dumper \@v; 

производит массив из 4 элементов,

$VAR1 = [ 
      '"server 1"', 
      '"server 2"', 
      '"server 3"', 
      '"server n"' 
     ]; 

Также отметим:

  • использование в SRV[] для имени параметра.
  • , а возвращаемые элементы массива содержат символы кавычек ".
+0

Не мог ли комментатор уменьшить, как я мог бы улучшить ответ? – jm666