何千ものログファイルがあり、すべて非常に大きいです。そのうちの1つに私が探しているIPアドレスがあります。私はそれがファイルの上部近くで起こる可能性が最も高いことを知っています。私はできます:
head -n 500 *.log | fgrep myip
「はい」と表示され、これはログファイルの1つにあります。それがどれであるかをどのように決定しますか?ファイルサイズのため、すべてのファイル(fgrep myip * .log)の内容全体をgrepすることはできません。
答え1
awkだけで脱出できます。
awk -v ip=127.0.0.1 'substr($0, ip) > 0 {print FILENAME ": " $0} FNR > 500 {nextfile}' *.log
現在の行でIPが見つかった場合は、IPとファイル名を印刷します。現在のファイル()の現在の行番号が500より大きい場合は、FNR
次のファイルにジャンプします。
答え2
このようなものが役に立ちます。
find . -iname "*.log" -print0 | xargs -0 -i{} bash -c 'echo "»»»File Name: {}«««"; head -n 500 {} | fgrep -B 501 myip'
長いファイル名のリストを生成し、最大500行の見つかったデータ、長いファイル名のリストを生成します。必要なファイル名は、長いデータ文字列の直前のファイル名です。
答え3
find -name \*.log -print0 |
xargs -0 sh -c 'for i; do head -n 500 $i | fgrep -q myip && echo $i; done
これは . で終わるすべてのファイル名を探し、その.log
リストをxargs
.-print0
xargs -0
xargs
後で指定されたコマンドxargs
とその引数は、コマンド呼び出しで適切なファイル名で実行されます。この場合、与えられたコマンドはsh
(シェル)であり、シェルは実行する小さなシェルスクリプトを提供します。
シェルスクリプトは基本的に次のようになります。
for i; do
head -n 500 $i | fgrep -q myip && echo $i
done
このfor i
部分は、シェルに指定されたすべての引数、つまりすべてのファイル名を繰り返します。各ファイル名に対して最初の500行を取得し、指定された文字列を検索します。fgrep -q
これは、fgrepが文字列を見つけたらすぐに停止することを意味します。文字列が見つかると、終了ステータスは「成功」、そうでなければ「失敗」です。最後に、これは&& echo $i
前のコマンドが「成功」状態の場合にエコーが実行されることを意味し、文字列が見つかるとファイル名が表示されることを意味します。
答え4
私はできます:
- すべてのファイルを繰り返します。
- 最初の500行を取得します。
- IPが次の行にあることを確認してください。
- その場合は、ファイル名を印刷してループを終了します。
コードで:
for f in ./*
do
head -n 500 "$f" | grep -qF myip && { printf "Found in: $f"; break; }
done
myip
お探しのIPと交換してください。目的のIPをパラメータとして取得する関数(またはシェルスクリプト)を作成できます。
findlogip ()
{
for f in ./*;
do
head -n 500 "$f" | grep -qF "$1" && {
printf "Found in: $f\n";
break
};
done
}
〜のようにエマルオコメント、誤って他のIPと一致しないように検索するIPに注意する必要があります(例では10.55.33.6ですが、110.55.33.68は一致します)。 GNU grepを使用してください(家庭、与えられたオペレーティングシステムタグ)、特定のIPアドレスをタグで囲むことができます\b
。
...
head -n 500 "$f" | grep -q "\b$1\b" && ...
...
-F
式はもはや「固定」式ではなく正規表現であるため(固定文字列)、grepオプションを削除します。