3

1つのフォルダー(ネストされた)に何百万ものファイルがあります。これらのファイルから値をスキャンし、この値を含む行を印刷する必要があります(たとえばLINE_TXT)。以前は各ファイルをsedしていましたが、これを行うには45分かかりました。私の以前の解決策は次のようなものでした:

FILES=$(find $1 -type f -name 'filename.txt')
for f in $FILES
do
    if [[ "$LINE" == *LINE_TXT* ]]; then
        echo $LINE
    fi
done

私は、パイプミルがこれを達成するための最良の方法であると考えました。私の主な解決策は次のようなものです:

makefifo mypipe
find $1 -type f -name 'filename.txt' | xargs cat > my pipe &
while read -r LINE
do
    if [[ "$LINE" == *LINE_TXT* ]]; then
        echo $LINE
    fi
done << mypipe

実行時間は約1分です。これをさらに改善できますか?

4

3 に答える 3

5

スクリプトのオーバーヘッドが少ないほど、処理が速くなるように思われます。

fgrep -r -h 'LINE_TXT' $1

grepに、ディレクトリを介して独自の再帰を実行させます-r。また、出力にファイル名を含めたくない場合は、-hオプションを含めます。後処理に必要なものは何でも出力をパイプできます。

特定のファイル名のみを検索する場合、grepの-rオプションには独自のオプションがあります:--includeおよび--exclude、manページに記載されています。例えば:

fgrep -h -r --include '*/filename.txt' 'LINE_TXT' $1

このfindコマンドは優れており、特定の状況では非常に貴重ですが、のような単一のツールに組み込まれているオプションを使用できる場合は、grepオーバーヘッドが少なくなります。findコマンドはファイル内を検索しないため、ファイルごとに起動するgrep必要があります。DIDを使用したい場合はfind、次のようになります。

find $1 -name 'filename.txt' -exec fgrep 'LINE_EXT' {} \;

findこれには、のディレクトリ検索機能へのアクセスを提供するという利点がありますが、ディレクトリツリーで特定の名前のファイルを検索するだけの場合は、grep-r --includeで十分であり、より高速に実行されます。

于 2012-12-02T14:15:17.070 に答える
1

はい、find $1 -type f -name 'filename.txt' | xargs fgrep LINE_TXT必要なのは、これらのファイルのいずれかで「LINE_TXT」のすべての一致を見つけることだけです。

于 2012-12-02T14:09:13.740 に答える
0

これは、ツールackag、およびripgrepの正確な使用例です。よりも使い勝手が良いだけでgrep -rなく、少なくとも後者の2つははるかに高速です。

于 2021-12-16T06:52:19.747 に答える