Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > нужна функция аналогичная implode из php


Автор: Alximik 27.7.2005, 23:23
чтоб сильно вас не напрягать поясню что она делает и для чего мне нужна такяже в perl возможно вам проще будет чтото мне подсказать.
и так функция implode в php помогает загрузить текстовый файл.

теперь объясняю что я хочу и для чего мне такая функция нужна:
есть каталог с файлами в формате *.txt скрипт должен загружать эти файлы. так вот какой функцией это можно сделать?

Автор: Anarki 27.7.2005, 23:55
join("string_glue", @array);
Параметры: строка клей, то бишь разделитель в новой строке, и массив

Код:
Код

#use strict;
use Tie::File;
use Fcntl;
my $path = "."; # текущая папка
my $dir = undef;
opendir($dir,$path);
while (defined(my $file = readdir($dir))) {
    next if (($file eq '.') || ($file eq '..')); # пропускаем не-файлы
    # работаем с каждым файлом, загружаем в массив
    my @data = (); # массив
    tie (@data, Tie::File, $file,mode => O_RDONLY) or die("File error :$!\n"); # загружаем файл в массив, файл открылся только для чтения
    my $str = join("\r\n",@data); # переводим массив в строку, где \r\n - разделитель строк файла(MS Windows)
    print "$str\n\n";
}

Автор: korob2001 31.7.2005, 10:53
Так мож но загружать их сразу в строку.
Код

open(F, "file.txt") or die $!;
my $full_file = <F>;
close(F);
#Здесь делаем что-то с переменной $full_file

Автор: Anarki 27.8.2005, 12:38
Написал аналог функции smile

Автор: Usya 27.8.2005, 13:02
korob2001

Если я не путаю, то кажется в коде вместо

Код

my $full_file = <F>;


надо

Код

my @full_file = <F>;


иначе получим только одну строчку из файла. А дальше работаем с массивом @full_file.
Хотя, если в файле нет разделителей строк, то вполне пойдет и твой вариант smile

Автор: korob2001 27.8.2005, 13:09
Опс... Sorry, перепутал с <>.

Автор: Usya 27.8.2005, 14:01
Alximik

Возможно и это тебе пригодится

Определить файлы в каталоге можно по крайней мере двумя способами:

@files=glob('.../dfsd/*.txt');

Иногда я им пользуюсь, однако

Цитата
Такой способ вызывает внешнюю программу glob (также, как и способ
@files=glob("*")). Это неправильно не только потому, что на запуск внешней
программы уходит время и ресурсы, но и потому, что где-нибудь этой программы
может просто не оказаться. Более правильный способ - это:

opendir DIR,'/tmp';
@files=readdir DIR;
closedir DIR;

или

opendir DIR,'/tmp';
while $file (readdir DIR)
{
}
closedir DIR;

Заметьте, что в $file будут подставляться как имена файлов, так и имена
подкаталогов.
Несколько подсказок. Чтобы прочесть список файлов, в котором не содержалось
бы '.' и '..', можно написать следующее:

opendir DIR,'/tmp';
@files=grep !/^\.+$/,readdir DIR;
closedir DIR;

Таким же способом,- с помощью regexp,- можно задавать любые другие маски
файлов.
Если вы хотите прочесть список каталогов, не трогая файлы:

opendir DIR,/tmp';
@dirs=grep {!/^\.+$/ and -d "/tmp/$_"} readdir DIR;
closedir DIR;


Тебе может подойти еще и такой вариант

Код

opendir DIR,'d:/';
@files=grep /\.txt$/,readdir DIR; # $ - означает, что .txt должно быть в конце строки
closedir DIR;


Раньше я так не делал, но вроде работает.
Если что неправильно, думаю меня подправят smile

Автор: korob2001 27.8.2005, 14:48
Цитата

Такой способ вызывает внешнюю программу glob (также, как и способ
@files=glob("*")). Это неправильно не только потому, что на запуск внешней
программы уходит время и ресурсы, но и потому, что где-нибудь этой программы
может просто не оказаться.

Usya - ты где это взял? smile

Автор: Usya 27.8.2005, 15:09
По крайней мере здесь точно есть:

http://www.sedinko.ru/perl/doc6.php


Автор: korob2001 28.8.2005, 09:34
Вообще-то glob это внутренняя функция. Только до версии 5.6 она использовала внешний процесс, начиная с версии 5.6 она использует внутренний поиск файлов по шаблону.

Автор: Usya 29.8.2005, 08:17
Возможно и так.

То, что

Цитата
начиная с версии 5.6 она использует внутренний поиск файлов


это я увидел, а на счет

Цитата
до версии 5.6 она использовала внешний процесс


может быть и так, хотя в доках что-то не нашел. Может плохо искал, может не совсем точно перевел.
Хотя, по большому счету, какая разница. Это важно когда что-то оптимизируешь, но тогда пробуешь все возможные варианты и потом выбираешь с учетом того, какая версия будет на серваке.

Автор: korob2001 29.8.2005, 15:19
Цитата

Возможно и так

Да не возможно, а так оно и есть. Перед тем как отвечать, я сам ещё раз открыл книгу "Программирование на Perl" Ларри Уолл, Том Кристиансен, Джон Орвант. Кому же как не создателю языка, лучше знать как работает та или иная функция?
Цитата

Это важно когда что-то оптимизируешь, но тогда пробуешь все возможные варианты и потом выбираешь с учетом того, какая версия будет на серваке.

Ну от серваков, где версия Perl ниже 5.6, нужно избавляться, как можно быстрее. smile

Автор: Usya 29.8.2005, 15:38
Теперь Верю! smile

Просто в таких вещах, как ты мне только что сам показал на ошибке в том FAQ-e, можно верить, по большому счету, только первоисточникам!!!

Автор: Player47 25.6.2006, 14:19
Здравствуйте,

Простите, что поднимаю из пыли старую тему, но вот почему-то не работает ни один из выше приведенных способов.

НО:

Я нашел очень толковый скрипт:

Код

#!/usr/bin/perl -w
use strict;
use diagnostics;
use File::Find;
sleep(5);
# Get the pattern from the input list
my $pattern = shift @ARGV;
# Slurp up the entire contents of a file
$/ = undef;
print qq{Searching for "$pattern".\n};
sleep(5);
# Invoke "find" with a reference to our subroutine,
# with the directories passed as arguments
find(\&find_matches, @ARGV);
sub find_matches
{
my $filename = $_;
# Open the file, and search through its
# contents
sleep(5);
if (open FILE, $filename)
{
# Get the file
my $contents = (<FILE>);
# If there aren't any contents, then return
# right away
return unless $contents;
# Print the filename, with the directory
print qq{$File::Find::dir/$filename\n}
if ($contents =~ m|\b$pattern\b|is);
close FILE;
}
else
{
warn qq{Unable to open
"$File::Find::dir/$filename": $! };
return;
}
}


А вот собственно сам поиск:

Код

#!/usr/bin/perl -w
use strict;
use diagnostics;
use File::Find;
# Invoke "find" with a reference to our
# subroutine, and the initial directory name
my @nested = ("sleep", "shit", "shell");
find(\&print_name, "worksongs");
sub print_name { print "$File::Find::name\n"; }


Проблемка в том, чтобы все это богатство не просто выводилось на экран,
а попадало в массив, с помощью которого потом можно будет работать...
Выручите, а?

 smile 

Заранее благодарен. 

Автор: sharq 27.6.2006, 10:07
Player47, в чем проблема? 
Вместо print сделай занесение в массив и в функции возвращай этот массив.

 smile  

Автор: Player47 3.7.2006, 17:30
Пишет набор ошибок...

Я пока в Perl'e совсем начинающий, что-то не понимаю, почему когда пишутся ошибки, программа закрывается - никакие sleep'ы не помогают. Может, я неправильно в массив записываю?

Я вот ей пишу: 1) открой массив (через @)
                         2) далее через last index number запиши этот самый Find:dir (вместо принта)
                         3) и вот - программа не снисходит даже до того, чтобы объяснить в чем дело!

В общем, я ее принтскрином поймал - так пишет неопознанный массив и все-такое... В чем я дурак?!!

 smile  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)