1

以下の例のように、perl grep を使用しています。「bfh」は、読み取り用に open コマンドによって作成されたファイル ハンドルです。

 @searchResults = grep {/,\s*${searchRecId}\s*,\s*${searchSwId}\s*/} <$bfh>;

ファイル ハンドル "bfh" の代わりに、UNIX の grep コマンドのようにパスを含むファイル名を直接指定できますか? やりたい場合、どのような変更を加える必要がありますか? 以下のコードは正しいですか?

@searchResults = grep {/,\s*${searchRecId}\s*,\s*${searchSwId}\s*/} /tmp/test.out

ファイル ハンドルまたは配列を指定したくありません。UNIXのgrepコマンドのようにやりたいだけです。

1000 個のファイルを grep します。100000 行のファイルを読み取るとき grep に関しては、1 行ごとに、1000 個のファイル ハンドルを開いてハッシュマップに保持する代わりに、ファイル名を直接取得したいと考えています。

4

2 に答える 2

3

を通じて行うことができますmap。たとえば、これ*.datは現在のディレクトリで grep を切り取ったものです。

my @searchResults = grep {
    /,\s*${searchRecId}\s*,\s*${searchSwId}\s*/
} map {
    sub {
        my @ret;
        if (open my $fh, "<", shift) {
            @r = <$fh>;
            close @fh;
        }
        return @ret;
    }->($_);
} glob "*.dat";

ただし、これは多くの行を含む多くのファイルを処理する場合、最適ではないアプローチです! これは、同じことを行うためのメモリ貪欲ではない方法です。

my @searchResults;
opendir(my $dh, '.') or die "error opening current directory: $!";
while (my $file = readdir $dh) {
    next unless -f $file;
    next if $file !~ /\.dat$/;
    if (open my $fh, '<', $file) {
        while (my $line = <$fh>) {
            if (/,\s*${searchRecId}\s*,\s*${searchSwId}\s*/) {
                push @searchResults, $line;
            }
        }
        close $fh;
    } else {
        die "error processing $file: $!";
    }
}
closedir $dh;

また、シェルに興味がある場合は、ackユーティリティを確認してください。

于 2012-12-05T12:42:10.680 に答える
1

あなたがすることができます:

use Slurp;
my $filename = 'my/file/name';
@searchResults = grep {/,\s*${searchRecId}\s*,\s*${searchSwId}\s*/}
                   slurp $filename;

ただし、これによりファイルがメモリに読み込まれます。

于 2012-12-05T12:36:20.210 に答える