2010-01-18 5 views
1

Мне нужно сделать 3 массива из содержимого $directory. Первый я могу использовать:Как создать массив содержимого каталога в Perl?

$var = qx{ls $directory}; 
print $var; 

Однако второй и третий я хочу вычленить информацию «Primary *» и «* Вторичные»

я использовал команды:

my @primary = 0; 
my @secondary = 0; 

@primary = system("ls test_77 > test | grep Primary* test"); 
print @primary; 
@secondary = system("ls test_77 > test | grep Secondary* test"); 
print @secondary; 

НО, она включает в себя ноль на выходе:

PrimaryCPE_Option_A.txt.test_77 
PrimaryCPE_Option_B.txt.test_77 
0SecondaryCPE_Option_A.txt.test_77 
SecondaryCPE_Option_B.txt.test_77 
0 

что это может быть? Сначала это выглядит как исходный ноль, но я могу изменить начальное значение, и он не работает.

+0

Избегайте 'системы', используя Perl, когда это возможно. – aartist

+0

Вы действительно собираете вывод ls в grep, или это то, что | действительно точка с запятой? Кажется странным перенаправить вывод ls в файл AND, и вывести его вывод в grep. – toolic

ответ

3

Perl может сделать это без вызова системных команд.

@secondary=glob("*Secondary*.txt"); 
print @secondary; 
@primary=glob("*Primary*.txt") 
print @primary; 

Другие способы используют opendir()/READDIR(), или в то время как петли, например

while(my $file=<*Primary*txt>){ 
    push(@secondary,$file); 
} 

Или

push (@secondary,$_) while<*Secondary*.txt> ; 
+0

Большое спасибо, это работает отлично. Вы все блестящие! – Soop

0

Думаю, вы должны использовать opendirreaddir и т. Д.).

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

(Обратите внимание, что вам нужно, чтобы избежать * в вашем grep, если вы будете продолжать с вашим подходом.)

3

Ниже будет читать все файлы в текущем каталоге, и сохраните их в один массив. Он исключает подкаталоги, но включает файлов, которые начинаются с символа .. Затем он создает 2 других массива из 1-го массива. См. File::Slurp.

use strict; 
use warnings; 
use File::Slurp qw(read_dir); 

my @all_files = grep { -f $_ } read_dir('./'); 
my @pfiles = grep {/^Primary/ } @all_files; 
my @sfiles = grep {/^Secondary/} @all_files; 

Постараюсь ответить на ваши вопросы сейчас. system возвращает статус выхода внешней команды (например, ls). Он не возвращает список каталогов. Вы должны использовать qx, чтобы вернуть список каталогов. См. system.

Итак, поскольку ваша команда ls преуспевает, ее статус выхода равен 0. Таким образом, system возвращает 0. Это значение сохраняется в 1-м элементе вашего массива. Это единственное значение в вашем массиве. Я думаю, что любой другой вывод, который вы видите, исходит от вашего grep.

Кроме того, единственный способ приблизиться к воспроизведению вашего выхода, чтобы изменить трубу точки с запятой в вашем system вызова, и избавившись от *:

@primary = system("ls test_77 > test ; grep Primary test"); 
1

Это, как я пишу это программа:

#! /usr/bin/env perl 
use strict; 
use warnings; 
use autodie; # this is so that you don't have to check opendir(), and readdir(). 

my @files = grep { 
    -f $_; 
} do{ 
    opendir my $dir, '.'; 
    readdir $dir; 
}; 

my @primary = grep {/Primary/ } @files; 
my @secondary = grep {/Secondary/} @files; 

Вы ставите 0 в списке, объявив массивы, как это:

my @primary = 0; 

Если вы хотите пустой массив, вы просто объявляете его.

my @primary; 

Если вы хотите явно задать массив ничего:

@primary =(); 
Смежные вопросы