LINUX.ORG.RU

В продолжение нубских вопросов о Perl

 ,


0

1

Задача простая - вывести список файлов в директории, и разбить его на массив.

Нагуглил как выполнить произвольную команду, и как разбить массив. Пишу:

$str = system "/usr/bin/find /home";

my @testarray = split "\n", $str;

print @testarray[0];

А оно выводит мне всю простыню файлов. Где я ошибся?

> Задача простая - вывести список файлов в директории, и разбить его на массив.

my @files = </home/*>;

print "$_\n" for @files;

если только файлов, то

my @files = grep { -f } </home/*>;
...
arsi ★★★★★
()
#! /usr/bin/perl

my $dir = shift @ARGV;
opendir my $dh, $dir or die "Can't find directory $dir";
my @dirs = readdir $dh;
closedir $dh;

print "$_\n" for @dirs;

Вызывается как perl ./script.pl /path/to/dir

bug
()

Ах, да, если файлов - arsi прав - ещё просей @dirs через grep {-f}

bug
()

Конкретно тут — в том, что system возвращает код завершения процесса. А простыня файлов — stdout от system, который ты не перехватил. В следующий раз используй $str = `/command/to/run`; (в обратных кавычках).

По поводу решения задачи уже сказали.

x3al ★★★★★
()
Ответ на: комментарий от arsi

Нужен именно рекурсивный обход всех каталогов, как делает find. Вывод вида:

/home/eugene/Downloads/pron.mp4
/home/eugene/Music/justin_bieber_oh_baby.ogg
/home/eugene/Pictures/lor.png
MyNameIsWinner
() автор топика
Ответ на: комментарий от MyNameIsWinner

> Нужен именно рекурсивный обход всех каталогов

use File::Find;
my @files;
find sub { push @files, $File::Find::name if -f }, '/home';
say for @files;
arsi ★★★★★
()

Инкременирую File::Find (или более удобный для сложных поисков File::Find::Rule с CPAN).

Кстати, если уж хотите грузить потенциально огромный список файлов в память, лучше использовать find -print0 и делить, соответственно, по нулевому байту, потому что \n - валидный символ в имени файла. Ещё лучше - при помощи pipe, fork и exec создать дочерний процесс, назначить local $/ = "\0" и читать файлы по одному при помощи $filename = <$pipe>.

AITap ★★★★★
()
Ответ на: комментарий от AITap

А если список будет действительно огромен (больше двух тысяч элементов), что будет быстрее работать - File::Find или вызывать файнд и его парсить?

Уточню что файлы свалены не в одну категорию, а находятся в огромном множестве подкаталогов.

MyNameIsWinner
() автор топика

/usr/bin/find непортабельно

надо использовать File::Find.

waker ★★★★★
()
Ответ на: комментарий от MyNameIsWinner

А если список будет действительно огромен (больше двух тысяч элементов), что будет быстрее работать - File::Find или вызывать файнд и его парсить?

find быстрее. на 2000 разницы скорее всего не будет (слишком мало).

waker ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.