2013-05-22 20 views
5

Napisałem program perl, aby pobrać wyrażenie z wiersza poleceń i wykonać rekursywne wyszukiwanie w bieżącym katalogu dla niektórych nazw plików i typów plików, grep dla każdego z wyrażeń regularnych, i wyświetla wyniki, w tym nazwę pliku i numer linii. [Podstawowy grep + odnaleźć funkcjonalność, że mogę iść i dostosować w zależności od potrzeb]

cat <<'EOF' >perlgrep2.pl 
#!/usr/bin/env perl 
$expr = join ' ', @ARGV; 

my @filetypes = qw(cpp c h m txt log idl java pl csv); 
my @filenames = qw(Makefile); 

my $find="find . "; 
my $nfirst = 0; 
foreach(@filenames) { 
    $find .= " -o " if $nfirst++; 
    $find .= "-name \"$_\""; 
} 
foreach(@filetypes) { 
    $find .= " -o " if $nfirst++; 
    $find .= "-name \\*.$_"; 
} 

@files=`$find`; 

foreach(@files) { 
    s#^\./##; 
    chomp; 
} 

@ARGV = @files; 

foreach(<>) { 
    print "$ARGV($.): $_" if m/\Q$expr/; 
    close ARGV if eof; 
} 
EOF 

cat <<'EOF' >a.pl 
print "hello "; 
$a=1; 
print "there"; 
EOF 

cat <<'EOF' >b.pl 
print "goodbye "; 
print "all"; 
$a=1; 
EOF 

chmod ugo+x perlgrep2.pl 
./perlgrep2.pl print 

Jeśli skopiuj i wklej to do swojego gniazda, widać to:

perlgrep2.pl(36): print "hello "; 
perlgrep2.pl(0): print "there"; 
perlgrep2.pl(0): print "goodbye "; 
perlgrep2.pl(0): print "all"; 
perlgrep2.pl(0):  print "$ARGV($.): $_" if m/\Q$expr/; 

Jest to bardzo zaskakujące mnie. Wygląda na to, że program działa, oprócz $. a zmienne $ ARGV nie mają wartości, których się spodziewałem. Z poziomu zmiennych wynika, że ​​perl już przeczytał wszystkie trzy pliki (łącznie 36 wierszy), gdy wykonuje pierwszą iterację pętli ponad <>. Co się dzieje ? Jak naprawić ? To jest Perl 5.12.4.

Odpowiedz

10

Używasz foreach(<>) gdzie powinieneś używać while(<>). foreach(<>) będzie czytał każdy plik z @ARGV na tymczasową listę przed zaczyna iterować nad nią.

+0

Dziękujemy! Muszę powiedzieć, że ostatnio czytałem dużo dokumentacji perla i nie wybrałem tego. – Colin

+0

Ah, więc "dla" ocenia <> w kontekście listowym, który odczytuje cały plik (lub pliki) na listę i podczas oceniania <> w kontekście skalarnym, który odczytuje następną linię. – Colin

+0

@Colin to prawda. – hobbs