grep? no.

Jun. 11th, 2003 01:18 pm
109: (Default)
[personal profile] 109
имеется много файлов, находимых по паттерну, в которых нужно найти строки, содержащие подстроку А и расположенные между строками, содержащими подстроки B и С. ответ должен обязательно содержать file name + line number, копия строки тоже желательна. какой тул поможет мне это сделать с минимальным геморроем?

(no subject)

Date: 2003-06-11 11:30 am (UTC)
From: [identity profile] msh.livejournal.com

Ну я бы сделал чего-то типа этого

#!/usr/bin/perl
use strict;
for my $file (glob($ARGV[0])){
  open(IN,$file) or die $!;
  my ($between,$line);
  for my $string (){
    $line++;
    $between = 1 if ($string =~ /B/);
    $between = 0 if ($string =~ /C/);
    print "$file:$line $string" if ($between && $string =~ /A/);
  }
  close(IN);
}


но в вашей области я и не знаю чего делают в таких случаях

(no subject)

Date: 2003-06-11 11:56 am (UTC)
From: [identity profile] 109.livejournal.com
я спинным мозгом чувствую, что программа написана с максимально возможной ясностью, но всё равно не понимаю ни хера. вот, например, что такое my($between, $line);? нет, никогда в жизни не буду на перле писать.

и эта... если 'С' вообще в файле нет, оно же не должно выводить ничего? а вроде будет... или нет?

(no subject)

Date: 2003-06-11 12:06 pm (UTC)
From: [identity profile] msh.livejournal.com
my($between, $line) - это просто объявление переменных. Я такой нетипичный перл-программист, делаю use strict
замечание верное, конечно. Думаешь я этот скрипт вообще запускал? ;-)

Пусть будет так

#!/usr/bin/perl
use strict;
for my $file (glob($ARGV[0])){
  open(IN,$file) or die $!;
  my ($between,$line,$msg);
  for my $string (<IN>){
    $line++;
    $between = 1 if ($string =~ /B/);
    if ($string =~ /C/){
      print $msg;
      $msg='';
      $between=0;
    }
    $msg.="$file:$line $string" if ($between && $string =~ /A/);
  }
  close(IN);
}

(no subject)

Date: 2003-06-11 12:50 pm (UTC)
From: [identity profile] 109.livejournal.com
а тут у тебя получается, что вывод будет только если А и С в одной и той же строке. нет?

(no subject)

Date: 2003-06-11 01:49 pm (UTC)
From: [identity profile] msh.livejournal.com
Ты чего, в Индии уже?

Если A то добавится в $msg, а если C - то $msg напечатается и очистится

Re:

Date: 2003-06-11 02:25 pm (UTC)
From: [identity profile] 109.livejournal.com
в Индию 19-го.

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

(no subject)

Date: 2003-06-11 01:54 pm (UTC)
From: [identity profile] 109.livejournal.com
вроде работает, непонятно почему :-)

как теперь его напустить на все файлы, удовлетворяющие маске, включая подкаталоги?

(no subject)

Date: 2003-06-11 02:49 pm (UTC)
From: [identity profile] msh.livejournal.com
Да я уж и не знаю, я бы find использовал, но если уж он не работает, пожет что-нибудь типа этого?

#!/usr/bin/perl
use strict;

traverse(@ARGV);

sub traverse($$){
  my ($path,$pattern)=@_;
  for my $file (glob("$path/*")){
    if (-d $file){
      traverse($file,$pattern);
    } elsif ($file =~ /$pattern/){
      process($file);
    }
  }
}

sub process($) {
  my $file = shift;
  open(IN,$file) or die $!;
  my ($between,$line,$msg);
  for my $string (<IN>){
    $line++;
    $between = 1 if ($string =~ /B/);
    if ($string =~ /C/){
      print $msg;
      $msg='';
      $between=0;
    }
    $msg.="$file:$line $string" if ($between && $string =~ /A/);
  }
  close(IN);
}

Profile

109: (Default)
109

March 2019

S M T W T F S
     12
3456789
101112131415 16
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags