最初の一致のみを1回印刷する

最初の一致のみを1回印刷する

ログ ファイルを解析し、必要な情報を印刷するために使用しているコード スニペットがあります。

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk '/\([a-zA-Z0-9.]+/ {print $7}' 
 done;

問題は、入力すると答えが複数回表示されることです。

(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.280.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.283.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109696.2)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109706.51)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109758.100)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109773.149)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109810.198)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109818.247)

これをトリミングして、最初の一連のデータを 1 回だけ表示できるようにする方法はありますか。1.3.51.0.1.1.10.10.30.48.2084865.2084839印刷する必要があるのは 1 回だけです。

これを次のように変更しようとしましたが、Bash ではうまくいきません。

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk '/\([a-zA-Z0-9.]+/' |
        awk -F'[(/]' ' {print $2, exit}'
done;

次にこれを試しました:

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk -F'[(/]' '/\([a-zA-Z0-9.]+/ {print $2, exit }'
done;

答え1

これを試して、

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk '/\([a-zA-Z0-9.]+/ {print $7; exit}' 
done;

exitawk コマンドは、最初の一致を出力した後に終了します。

または

コマンドの出力をfor以下のawkコマンドにパイプするだけです。

for .... | awk -F'[(/]' '{print $2;exit}'

答え2

ループは必要ありませんfor。1 回の呼び出しでgrepファイルから一致する行がすべて出力されるため、ファイル内の行数と同じ回数だけ同じ操作を繰り返すだけです。

awk技術的には、どちらもテキストマッチングが可能なため、両方またはどちらか一方は必要ありませんgrep。より具体的な回答が必要な場合は、ログ ファイルの抜粋と必要な出力の例を投稿してください。

答え3

実際に何をしているのか説明されていないので、いくつかの仮定を立てます。 というスクリプトを実行し、文字列とファイル名を引数として与えていると仮定します。これらはそれぞれとにfoo.shなります。おそらく、次のようなスクリプトを実行しているのでしょう。$1$2

foo.sh SearchPattern LogFileName

いずれにせよ、ループはi)ループによって作成された変数をfor使用していないので完全に役に立たない。ii)各変数の値を取得するため非常に間違っている。ifor i in ...i言葉おそらくあなたが考えていた行全体ではなく、iii) すべての問題の原因です。まったく同じコマンドを複数回実行しているため、同じ結果が複数回得られます。ファイルの行ごとに 1 つの結果が得られます。

とにかく、あなたが望むことは、次のような簡単なことで実現できます

grep "$1" ~/jlog/"$2" | awk '/\([a-zA-Z0-9.]+/ {print $7}' 

あるいは、もっと簡単に言うと:

awk '/'"$1"'/\([a-zA-Z0-9.]+/ {print $7}' ~/jlog/"$2"

awkは一重引用符で囲まれていないことに注意してください。これにより、bash はそれを に渡す前に、"$1"現在保持されている内容に展開します。$1awk

関連情報