2013-05-22 14 views
5

私はperlプログラムを書いてコマンドラインから正規表現を取り出し、特定のファイル名とファイルタイプに対して現在のディレクトリを再帰的に検索し、ファイル名や行番号などの結果を出力します。 [基本的なgrepの+必要に応じて私が行くとカスタマイズできる機能を見つける]

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 

コピーしてお使いの端末にこれを貼り付ける場合は、この表示されます。

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/; 

をこれはに非常に驚くべきことです私。プログラムは、$を除いて動作しているように見えます。 $ ARGV変数には私が期待した値がありません。変数の状態から、perlは<>以上のループの最初の反復を実行するときに3つのファイル(合計36行)を既に読み込んでいるように見えます。どうしたの ?直し方 ?これはPerl 5.12.4です。

答えて

10

while(<>)を使用する必要があるforeach(<>)を使用しています。 foreach(<>)@ARGVのすべてのファイルをより前のテンポラリリストに読み込みます。

+0

ありがとうございました!私は最近、たくさんのperlのドキュメントを読んでいると言わなければなりません。 – Colin

+0

ああ、 "for"はリストコンテキストで<>を評価し、ファイル全体をリストに読み込み、スカラーコンテキストで<>を評価しながら次の行を読み込みます。 – Colin

+0

@コリンそうです。 – hobbs

関連する問題