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.
Dziękujemy! Muszę powiedzieć, że ostatnio czytałem dużo dokumentacji perla i nie wybrałem tego. – Colin
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
@Colin to prawda. – hobbs