1

数百のログ ファイルから 200 までのファイル名を効率的に検索したいと考えています。

grep-fディレクティブを使用して針をファイルに入れることで、これを簡単に行うことができます。

ただし、いくつかの問題があります。

  • grepを効率的に使用する方法のように、これを効率的に行うことに興味があります。
  • すべてのログ ファイルの検索語 (ファイル名など)のすべての一致を個別に知りたいです。grep -f各ファイルで針を見つけると一致します。
  • ファイル名がどこにも一致しない場合を知りたいです。

2.7 i7 MBP、16 GB の RAM 搭載

を使用するgrep -ron -f needle *と、次のことがわかります。

access_log-2013-01-01:88298:google
access_log-2013-01-01:88304:google
access_log-2013-01-01:88320:test
access_log-2013-01-01:88336:google
access_log-2013-01-02:396244:test
access_log-2013-01-02:396256:google
access_log-2013-01-02:396262:google

含まれる場所needle:

google
test

ここでの問題は、一致するものがないかディレクトリ全体が検索されneedle、プロセスがシングルスレッドであるため、永遠にかかることです。また、一致が見つからないかどうかについての明確な情報もありません。

4

2 に答える 2

1

どの針が一致しなくなったかを判断するには、grep からの出力を取得して、次のようにします。

  1. awk などを使用して、一致した文字列だけを別のファイルに抽出します。
  2. その針ファイルをそのファイルに連結します
  3. 行うsort --uniq filename -o temp1
  4. needles ファイルを temp1 に連結します。
  5. 行うsort temp1 -o temp2
  6. uniq -u temp2 > temp3

temp3 には、使用されなくなった針が含まれます。

それを行うためのより簡潔な方法があるかもしれません。手順 1 ~ 3 では、ファイル内で見つかった一意の針のリストを取得します。

あなたの針ファイルが含まれているとしましょう:

google
foo
bar

また、grep は複数のファイルで foo と bar を見つけますが、google は見つけません。ステップ 1 では、次のようなファイルが作成されます。

foo
bar
bar
foo
foo
bar
foo

sort --uniq作成します:

foo
bar

針ファイルを連結すると、

foo
bar
google
foo
bar

ソートすると次のようになります。

bar
bar
foo
foo
google

そして、最後のuniq -uコマンドは 1 行を出力します。

google
于 2013-09-25T20:13:22.587 に答える
1

grepfindを bash スクリプトで組み合わせてみてはどうでしょうか。

for needle in $(cat needles.txt); do
    echo $needle
    matches=$(find . -type f -exec grep -nH -e $needle {} +)
    if [[ 0 == $? ]] ; then
        if [[ -z "$matches" ]] ; then
            echo "No matches found"
        else
            echo "$matches"
        fi
    else
        echo "Search failed / no matches"
    fi
    echo
done

needles.txtターゲットファイル名のリストが含まれています。

ファイルから針 (スペースを含むことができるようになりました) を 1 行ずつ読み取るには、次のバージョンを使用します。

cat needles.txt | while read needle ; do
    echo $needle
    matches=$(find . -type f -exec grep -nH -e "$needle" {} +)
    if [[ 0 == $? ]] ; then
        if [[ -z "$matches" ]] ; then
            echo "No matches found"
        else
            echo "$matches"
        fi
    else
        echo "Search failed / no matches"
    fi
    echo
done

との組み合わせを行うとxargs、エラーコード $? 成功してもゼロではなくなりました。これは安全性が低いかもしれませんが、私にとってはうまくいきます:

cat needles.txt | while read needle ; do
  echo $needle
  matches=$(find . -type f -print0 | xargs -0 -n1 -P2 grep -nH -e "$needle")
  if [[ -z "$matches" ]] ; then
        echo "No matches found"
  else
        echo "$matches"
  fi
  echo
done
于 2013-09-25T20:01:29.970 に答える