URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9407
[ Назад ]

Исходное сообщение
"Perl. Вопрос по поиску соответствия в строке"

Отправлено Goshik1 , 11-Мрт-12 19:04 
Доброго времени суток!

Никак не получается разобраться ((
Задача такая: есть два текстовых файла с разными длинами строк (во втором файле строка с пробелами).
Необходимо проверить присутствуют ли строки из первого файла в строках второго. И если присутствуют, то вывести эти строки в третий файл.

#!/usr/bin/perl -w            
          
#Открываем файл активных списка и заносим в массив
open (KILL,"kill.txt") || die "$!";
@kill=<KILL>;
close (KILL);

#Открываем файл активных сессий и заносим в массив
open (SESSION,"session.txt") || die "$!";
@ses=<SESSION>;
close (SESSION);

#Открываем файл-результат
open (KILL_SES,">kill_ses.txt") || die "$!";

#Определяем размеры массивов
$size1=@kill;
$size2=@ses;

$i=0;
while ($i<$size1) {
           $temp1=$kill[$i];
                   $j=0;
               while ($j<$size2) {
                                      $_=$ses[$j];
#    промежуточная проверка          print $_;
#    промежуточная проверка          print $temp1;
                      if (/$temp1/) { print KILL_SES $_; }
                                      $j++;
                     }
                   $i++;  
                  }
close (KILL_SES);

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


Содержание

Сообщения в этом обсуждении
"Perl. Вопрос по поиску соответствия в строке"
Отправлено user , 11-Мрт-12 19:30 
>[оверквотинг удален]
>     $j++;
>          }
>            
>        $i++;
>            
>       }
> close (KILL_SES);
> Проблема в том, что не получается вычленить искомые строки. Переменные выводит верно,
> но в файл-результат ничего не попадает. Где-то я накосячил в проверке,
> но где понять не могу.

вставте отладочные выводы через print текущих значений переменных.


"Perl. Вопрос по поиску соответствия в строке"
Отправлено Square , 12-Мрт-12 02:10 
foreach $r (@kill){foreach $t (@ses){if ($t=~/$r/){print $t;}}}

Но вообще ваш пример работает. Все он создает...


"Perl. Вопрос по поиску соответствия в строке"
Отправлено Goshik1 , 12-Мрт-12 10:20 
> foreach $r (@kill){foreach $t (@ses){if ($t=~/$r/){print $t;}}}
> Но вообще ваш пример работает. Все он создает...

У меня он промежуточные переменные выводит правильно, но в файл-результат не записывает. С Вашим примером тоже ((

Вот пример текстовых файлов, чтобы было понятнее.

массив kill:
username1
username2

массив ses:
СЕАНС             ПОЛЬЗОВАТЕЛЬ             ID  СТАТУС  ТИП         УСТР-ВО
console                                     0  Џ®¤Є«о祭®  wdcon              
rdp-tcp                                 65538  ЏаЁҐ¬   rdpwd              
rdp-tcp#31        username1                 1  ЂЄвЁў­®  rdpwd              

Скрипт должен проверять присутствует ли элемент массива kill (username1) в элементе массива (строке) ses.  Т.е. в итоговый файл должна попасть полностью строка:
rdp-tcp#31        username1                 1  ЂЄвЁў­®  rdpwd


"Perl. Вопрос по поиску соответствия в строке"
Отправлено PavelR , 12-Мрт-12 10:39 
>> foreach $r (@kill){foreach $t (@ses){if ($t=~/$r/){print $t;}}}
>> Но вообще ваш пример работает. Все он создает...
> У меня он промежуточные переменные выводит правильно, но в файл-результат не записывает.

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

- не срабатывает условие
- не производится запись

Добавь еще один отладочный print .


"Perl. Вопрос по поиску соответствия в строке"
Отправлено Goshik1 , 12-Мрт-12 11:00 
>>> foreach $r (@kill){foreach $t (@ses){if ($t=~/$r/){print $t;}}}
>>> Но вообще ваш пример работает. Все он создает...
>> У меня он промежуточные переменные выводит правильно, но в файл-результат не записывает.
> Ты, как программист скрипта, должен понять, что отсутствие вывода в файл может
> быть по двум причинам :
> - не срабатывает условие
> - не производится запись
> Добавь еще один отладочный print .

Добавил. Я считаю, что не срабатывает условие, потому что нижеприведенный скрипт всегда выдает "Условие не выполнено". Хотя на последних элементах массивов есть совпадение:

#Определяем размеры массивов kill и ses
$size_k=@kill;
$size_s=@ses;

print "Размер массива kill: ",$size_k,"\n";
print "Размер массива ses: ",$size_s,"\n";

#Обнуляем счетчик
$i=0;

while ($i<$size_k) {
           $temp1=$kill[$i];
           print "Текущий элемент массива kill: ",$temp1,"\n";
                   $j=0;
               while ($j<$size_s) {
                                    $temp2=$ses[$j];
                                    print "Текущий элемент массива ses: ",$temp2,"\n";
                                if ($temp2=~/$temp1/) { print "Условие выполнено\n"; }
                    else { print "Условие не выполнено \n"; }
                                    $j++;
                      }
                   $i++;  
                  }


"Perl. Вопрос по поиску соответствия в строке"
Отправлено PavelR , 12-Мрт-12 11:35 
>>>> foreach $r (@kill){foreach $t (@ses){if ($t=~/$r/){print $t;}}}
>>>> Но вообще ваш пример работает. Все он создает...
>>> У меня он промежуточные переменные выводит правильно, но в файл-результат не записывает.
>> Ты, как программист скрипта, должен понять, что отсутствие вывода в файл может
>> быть по двум причинам :
>> - не срабатывает условие
>> - не производится запись
>> Добавь еще один отладочный print .
> Добавил. Я считаю, что не срабатывает условие, потому что нижеприведенный скрипт всегда
> выдает "Условие не выполнено". Хотя на последних элементах массивов есть совпадение:

Хы.

А выводит оно у тебя так:

Текущий элемент массива kill: XXXXX
[ПУСТАЯ СТРОКА]
Текущий элемент массива ses:  YYYYY
[ПУСТАЯ СТРОКА]
Условие не выполнено


верно? ;-)


"Perl. Вопрос по поиску соответствия в строке"
Отправлено Goshik1 , 12-Мрт-12 11:46 
> Хы.
> А выводит оно у тебя так:
> Текущий элемент массива kill: XXXXX
> [ПУСТАЯ СТРОКА]
> Текущий элемент массива ses:  YYYYY
> [ПУСТАЯ СТРОКА]
> Условие не выполнено
> верно? ;-)

Да, нечто вроде было :-)
Разобрался, немного переделав скрипт :-)
Рабочий скрипт ниже (если кому-нибудь будет интересно):

#Открываем файл списка пользователей на отключение и заносим в массив
open (KILL,"kill.txt") || die "$!";
@kill=<KILL>;
close (KILL);

#Открываем файл активных сессий и заносим в массив
open (SESSION,"session.txt") || die "$!";
@ses=<SESSION>;
close (SESSION);

#Открываем файл-результат на запись
open (KILL_SES,">kill_ses.txt") || die "$!";

#Определяем размеры массивов kill и ses
$size_k=@kill;
$size_s=@ses;

print "Размер массива kill: ",$size_k,"\n";
print "Размер массива ses: ",$size_s,"\n";

#Обнуляем счетчик
$i=0;
while ($i<$size_k)
   {
   $temp1=$kill[$i];
   @words1=map{split ' ',$_} $temp1;
#  print "words1= ",@words1,"\n";
#  print "Текущий элемент массива kill: ",$temp1,"\n";
   $j=0;
   while ($j<$size_s) {
                      $temp2=$ses[$j];
#                     print "Текущий элемент массива ses: ",$temp2,"\n";
              @words2=map{split ' ',$_} $temp2;
#              print "words2= ",@words2,"\n";
                      if (grep /@words1/,@words2)
                         { print "Условие выполнено \n";
               print KILL_SES $temp2; }
              else { print "Условие не выполнено \n"; }              
   $j++;
                  }
$i++;  
  }
close (KILL_SES);


"Perl. Вопрос по поиску соответствия в строке"
Отправлено PavelR , 12-Мрт-12 15:05 
>[оверквотинг удален]
>> А выводит оно у тебя так:
>> Текущий элемент массива kill: XXXXX
>> [ПУСТАЯ СТРОКА]
>> Текущий элемент массива ses:  YYYYY
>> [ПУСТАЯ СТРОКА]
>> Условие не выполнено
>> верно? ;-)
> Да, нечто вроде было :-)
> Разобрался, немного переделав скрипт :-)
> Рабочий скрипт ниже (если кому-нибудь будет интересно):

Надо было подчистить концы строк примерно так:

$temp1=~s/\r//;
$temp1=~s/\n//;

ну и во второй переменной аналогично.

Хотя в одной из них в общем-то не надо (котораЯ регуляркОЙ проверяется - может содержать конец строки, но матчиться.)


"Perl. Вопрос по поиску соответствия в строке"
Отправлено Goshik1 , 12-Мрт-12 15:53 
>[оверквотинг удален]
>>> верно? ;-)
>> Да, нечто вроде было :-)
>> Разобрался, немного переделав скрипт :-)
>> Рабочий скрипт ниже (если кому-нибудь будет интересно):
> Надо было подчистить концы строк примерно так:
> $temp1=~s/\r//;
> $temp1=~s/\n//;
> ну и во второй переменной аналогично.
> Хотя в одной из них в общем-то не надо (котораЯ регуляркОЙ проверяется
> - может содержать конец строки, но матчиться.)

Спасибо, попробую.


"Perl. Вопрос по поиску соответствия в строке"
Отправлено Square , 12-Мрт-12 19:22 
>> foreach $r (@kill){foreach $t (@ses){if ($t=~/$r/){print $t;}}}
>> Но вообще ваш пример работает. Все он создает...
> У меня он промежуточные переменные выводит правильно, но в файл-результат не записывает.
> С Вашим примером тоже ((

Мой пример в файл ничего не пишет, он выводит на экран. Я написал его только для того чтобы показать вам как легко и просто решается ваша задача без этих ужасных циклов с счетчиками и определением размера массива :)

Если! Мой паример! Таки выведет вам на экран строки!

то сохранив скрипт в файл можно сделать так:

perl скрипт.pl > файл_в котором_сохранится_то_что_он_вывел_на_экран

На самом деле,  ваш пример, когда его запускаю я, создает файл с правильным содержимым.

Промежуточную проверку нужно вставить не только перед проверкой условия, но и в результат проверки условия:

#    промежуточная проверка          
print $_;
#    промежуточная проверка          
print $temp1;
                      if (/$temp1/) {
#    промежуточная проверка          
print $_;
#    промежуточная проверка          
print $temp1;
                        print KILL_SES $_;
};