К списку форумов К списку вопросов
Perl: содержание файла в строку
ZhelR
26.03.2004 - 16:09
приветствую, сразу оговорюсь, что с perl не знаком совсем, но с Вашей помошью надеюсь решить такую задачу:
у меня есть скрипт, который по расписанию проверяет определенную папку на наличие появившихся там файлов, он анализирует их название и в зависимости от результатов перемешает в определенное место и шлет пользователю мыл, что типа файл такой-то и такой-то пришел туда-то. Тип файлов текст. Так вот мне бы хотелось, что бы скрипт добавлял к телу писма еще и содержимое файла. Не подскажете как реализовать
Уверенный
1 - 26.03.2004 - 16:30
Без скриптика сложно будет советовать. Надо в то место, где письмо отправляется, добавить печать переменой, в которую предварительно прочитать файл:
 
{
 local $/ = undef;
 open IN, "/path/to/file" or die "can't open file: $!";
 my $buf = <IN>;
 close IN;
}
#.... тут формирование сообщения
print $buf;
Alexander Smith
2 - 26.03.2004 - 16:33
$work_dir="/usr/local/home/your/";
.
.
.
open(F, "<".$work_dir.$file_name[$i]);
my @file_lines;
$#file_lines=-1;
@file_lines=<F>;#@file_lines-массив строк
close(F);
if ($file_lines[0]!~m/\r\n/)#определил юникс или вин текст формат
{
 for(my $i=0; $i<=$#file_lines; $i++)
 {
  $file_lines[$i]=~s/\n/\r\n/;#так надо, для SMTP демона стандартного..
 };
};
$result_line=join("", @file_lines);
Alexander Smith
3 - 26.03.2004 - 16:36
коментарий к #2 - если отправляется письмо сендмэйлом, то if ($file_lines[0]!~m/\r\n/) и все что внутри него - не надо.
для #1 а разве $buf будет содержать весь файл, а не только 1-ую строку ?
ZhelR
4 - 26.03.2004 - 16:58
вот кусочек, который смотрит за папкой:
elsif ((/\bxinfo/i)or(/\bpismo/i)) {
    $message = "Пришло письмо $_ в \\letters";
    system "move /y $_ $CBDir.\\letters";
    system "net send * $message";
    SMail();
    print LOG "$day.$month.$year - _аЁи<R ЇЁбм&#9488;R $_\n"}
функция, которая шлет письма:
sub SMail {
  my $address = 'zhelr@pskb.spb.ru';
  my $smtp = Net::SMTP->new('pscb-exch');
  $smtp->mail($ENV{USER});
  $smtp->to($address);
  $smtp->data();
  $smtp->datasend("To: Zhelonkin Roman <zhelr@stdpod.spb.ru>\n");
  $smtp->datasend("From: TestMail\n");
  $smtp->datasend("\n");
  $smtp->datasend("$message\n");
  $smtp->dataend();
  $smtp->quit;
}
Уверенный
5 - 26.03.2004 - 21:28
3, а это не ты заметил: local $/ = undef; ? Т.е. временно "убиваем" разделитель записей.
Alexander Smith
6 - 26.03.2004 - 23:42
#5 - э.. не заметил. :-)
mae
7 - 29.03.2004 - 13:23
>> local $/ = undef;
>> open IN, "/path/to/file" or die "can't open file: $!";
>> my $buf = <IN>;
>> close IN;
Вообще-то это делается так:
open *IN, "/path/to/file";
read *IN, my $buf, -s *IN;
close *IN;
,
Alexander Smith, ты слишком намудрил с \n и \r\n. В перле '\n' - это универсальный _логический_ символ перевода строки. И на любой операционной системе (хоть даже в маке) перл сам будет подставлять тот перевод строки, который нужен.
ZhelR
8 - 29.03.2004 - 14:51
у меня получилось как в (2), а в (7) получу такой же результат ?
mae
9 - 30.03.2004 - 08:51
Разумеется. Причём быстрее. Смысл в том, что read - функция для чтения из потока. И она читает напрямую "от забора и до обеда". Работает быстрее, чем читать так: $buf=<IN>;
Уверенный
10 - 30.03.2004 - 12:47
Решил проверить:
 
use strict;
 
use Benchmark qw(cmpthese);
 
cmpthese(1000,
  {
    dda => sub {
                  open *IN, "test.txt";
                  read *IN, my $buf, -s *IN;
                  close *IN;
    },
    mae => sub {
                  local $/ = undef;
                  open IN, "test.txt";
                  my $buf = <IN>;
                  close IN;
     }
  }
);
 
Запускал три раза:
 
D:\TEMP\B>test.pl
Benchmark: timing 1000 iterations of dda, mae...
       dda: 2 wallclock secs ( 1.31 usr + 0.62 sys = 1.93 CPU) @ 517.87/s (n=1000)
       mae: 3 wallclock secs ( 1.67 usr + 0.59 sys = 2.26 CPU) @ 441.89/s (n=1000)
     Rate mae dda
mae 442/s -- -15%
dda 518/s 17% --
 
D:\TEMP\B>test.pl
Benchmark: timing 1000 iterations of dda, mae...
       dda: 2 wallclock secs ( 1.33 usr + 0.59 sys = 1.92 CPU) @ 520.56/s (n=1000)
       mae: 2 wallclock secs ( 1.74 usr + 0.47 sys = 2.21 CPU) @ 451.88/s (n=1000)
     Rate mae dda
mae 452/s -- -13%
dda 521/s 15% --
 
D:\TEMP\B>test.pl
Benchmark: timing 1000 iterations of dda, mae...
       dda: 2 wallclock secs ( 1.14 usr + 0.88 sys = 2.02 CPU) @ 494.56/s (n=1000)
       mae: 2 wallclock secs ( 1.51 usr + 0.68 sys = 2.19 CPU) @ 456.00/s (n=1000)
     Rate mae dda
mae 456/s -- -8%
dda 495/s 8% --
 
Вроде получается, что моя даже чуть быстрее. Но в принципе одинаково :)
Да, файл test.txt - 120 кил, повторенная 35 раз эта страница.
ZhelR
11 - 30.03.2004 - 16:56
Спасибо, мудрые отцы, а может не сочтете за труд подсказать, как на лету перекодировать из dos в win так же легко и изяшьно ?
С Уважением.
Уверенный
12 - 30.03.2004 - 18:02
#!/usr/bin/perl -w
use strict;
 
my $buf;
{
 local $/ = undef;
 open IN, "test.txt" or die "can't open file: $!";
 $buf = <IN>;
 close IN;
}
 
print dos2win($buf);
 
sub dos2win {
  my $string = shift;
    $string =~ tr


    return $string;
}
 
Взято тут: http://snipurl.com/5eao :)
Уверенный
13 - 30.03.2004 - 18:05
Мдя... Все порезал форум :(
Бери тут: http://dda.perlmonk.org/files/recode.zip
Уверенный
14 - 30.03.2004 - 18:09
Если "изящно", то можно и так:
 
use Encode;
from_to($buf, 'cp866', 'cp1251');
 
Но подозреваю, что этот модуль у тебя не установлен.
http://search.cpan.org/~dankogai/Encode-1.99/Encode.pm
ZhelR
15 - 30.03.2004 - 22:29
(14) скачал модуль положил его в C:/Perl/lib а он пишет, хотя Alias.pm лежит тамже:
Can't locate Encode/Alias.pm in @INC (@INC contains: C:/Perl/lib С:/Perl/site/lib .) at C:/Perl/lib/
Encode.pm line 46.
BEGIN failed--compilation aborted at C:/Perl/lib/Encode.pm line 46.
Compilation failed in require at testmail.pl line 9.
BEGIN failed--compilation aborted at testmail.pl line 9.
Уверенный
16 - 31.03.2004 - 09:40
Чтобы этот модуль заработал, скопировать .pm файлы недостаточно. Кстати, если написано "Can't locate Encode/Alias.pm", то перл пытается найти файл Alias.pm не в том же каталоге, что и Encode, а в подкаталоге с именем Encode, и это правильно.

К списку вопросов на форуме Веб-дизайн

>>