Forum Webscript.Ru

Программирование => Perl => Тема начата: domashniy от 14 Апреля 2005, 20:06:57

Название: экранирование регулярных
Отправлено: domashniy от 14 Апреля 2005, 20:06:57
вообщем мои скудные познания опять завели в тупик.
на это раз вроде все правильно написал, но нету счастья
вот что имею

my $logdir = "design_free";
opendir (G,"$logdir") or die $!; @z= (readdir G); closedir(G);
foreach (@z)
   {
   my $a = $_;
   my $b = $_;
   $b =~ s/-/_/g;
   opendir (G2,"$logdir/$a") or die $!; @x=grep (/\\.html/i, readdir G2); closedir(G2);
   foreach (@x)
      {
      my $a2 = $_;
      my $b2 = "$b.html";
open(F1,"$logdir/$a/$a2");
open (new,">$logdir/$a/$b2");
 $l1=;
   while( $l1 || 0)
   {
     $l1 =~ s/$a/$b/g;
     print new "$l1";
     $l1=;
   }
close (new);                                                                    
close(F1);                                                                      
      print "$b2\\n";
      }
   print "$b\\n";
   }

подскажите что не так и как мне быть
Название: экранирование регулярных
Отправлено: Phoinix от 15 Апреля 2005, 10:41:03
domashniy

Обедительная просьба код вписывать в тег [PHP]

Цитировать
на это раз вроде все правильно написал, но нету счастья


Вопрос в том, что ты хотел получить?

Во-первых: используй use strict - он тебе сразу покажет ошибки;
Во-вторых: new использовать в качестве FILEHANDLE нельзя, это все-таки оператор.
Название: экранирование регулярных
Отправлено: cr4ck3r от 15 Апреля 2005, 12:14:18
Да на редкость кривой код. Без обид.
Несколько советов (несмотря на то что я так и не понял что этим кодом ты хотел сделать).
Считывай содержимое каталога так:

@z= grep(!/^\\.\\.?$/,readdir G);

это исключит значения текущего и родительского каталогов (. и .. соответственно).

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


#!/usr/bin/perl

my $dir=\'.\';  #откуда пойдем плясать
my $idx_ext=\'.pdf\'; #что ищем
&recur($dir);
 
sub recur                  
{
 my $dir = shift;
 opendir DIR, $dir or return;
 my @contents = map "$dir/$_", sort grep !/^\\.\\.?$/, readdir DIR;
 closedir DIR;
 foreach (@contents)
  {
   if (!-l && -d)
    {
     recur($_);}
    }
   else
    {
     if ($_ =~ /$idx_ext$/i)
      {
 
      #делаем что-то с файлом совпадающим с шаблоном  
 
      }
     else { next; }
    }
  }
}


PS
Использование тэгов  PHP - кривое, так как убиваются обратные слэши типа \\.
Пример:

@z= grep(!/^\\.\\.?$/,readdir G);

Надо использовать [code] - как в моем примере ;-)
Название: экранирование регулярных
Отправлено: domashniy от 15 Апреля 2005, 13:17:58
Вообщем моя ошибка в то что не сказал что мне нужно, в конечном итоге.
Есть dir  в ней есть dir-name1, dir-name2, dir-name3
в dir-name1, 2, 3 есть файлы, мне нужно выбрать только один тип файлов по расширению (например .html)
далее самое интересное.
В этом файле мне нужно поменять все dir-name1 на dir_name1 и только в каталоге dir-name1, для другого нужно сот-но все dir-name2 на dir_name2 и только в каталоге dir-name2
Вот что хотел получить. Но почемуто ничего не вышло.

и еще раз скажу что не программер я ;(( так что не следует ждать от меня великих кодов.
Буду очень признатиелен за грамотно написанный код
Название: экранирование регулярных
Отправлено: cr4ck3r от 15 Апреля 2005, 14:05:57
Думаю этот код сделает то что вы хотите:

#!/usr/bin/perl -w

my $dir=\'./dir\';  #откуда пойдем плясать
my $idx_ext=\'.html\'; #что ищем
recur($dir);

sub recur
{
 my $dir = shift;
 opendir DIR, $dir or return;
 my @contents = map "$dir/$_", sort grep !/^\\.\\.?$/, readdir DIR;
 closedir DIR;
 foreach (@contents)
  {
   if (!-l && -d)
    {
     recur($_);
    }
   else
    {
     if ($_ =~ /$idx_ext$/i)
      {

      edit($_);

      }
     else { next; }
    }
  }
}

sub edit {
my $filename=shift;
print "Edit $filename\\n";
my $cur_dir=(stat(split(/\\//,$filename)))[2];
print "Change $cur_dir to";
$ed_dir=$cur_dir;
$ed_dir=~s/[-]/_/;
print " $ed_dir\\n";
open(FILE,"<",$filename) || die "$!\\n";
open(NEW,">","$filename.new") || die "$!\\n";

while() {
chomp;
s/$cur_dir/$ed_dir/;
print NEW $_,"\\n";
}
close(FILE);
close(NEW);
unlink($filename);
rename("$filename.new",$filename);
}

Название: экранирование регулярных
Отправлено: domashniy от 15 Апреля 2005, 14:37:50
спасибо проверю ваш код, но мой тоже заработал, оказалось все очень глупо не нужно вот этого было  $b =~ s/-/_/g; т.к. у меня уже правильные диры были, адальше просто лажа шла.
Но спасиб все одно и ваш код проверю ;)
Название: экранирование регулярных
Отправлено: ondr от 15 Апреля 2005, 15:35:44
perldoc File::Find

ps: также советую ознакомиться со всей линейкой модулей File::* из Perl поставки