Bashスクリプトから複数行をパイプします。

Bashスクリプトから複数行をパイプします。

解析する必要がある複雑なログがあります。私が望むのは文字列を見つけることです時間、一致する行から列 5 を取得し、列 5 が文字列と一致する他のすべての行を取得します。時間

入力例

a b c d 31 1
a b c d 31 H
a b c d 31 2
a b c d 32 1
a b d d 32 2
a b c d 33 1
a b c d 33 H
a b c d 33 2

期待される出力

a b c d 31 1
a b c d 31 H
a b c d 31 2
a b c d 33 1
a b c d 33 H
a b c d 33 2

したがって、2つの別々のスクリプトを作成してこれを行うことができます。 script1 | xargs -n1 | script2

スクリプト1検索文字列時間を押してから、5番目の列を印刷します。
cat logfile | grep 'H' | awk '{print $5}'

スクリプト2次に、列5は、最初のスクリプトの出力と一致するログファイルの他のすべての行を印刷します。 cat logfile | awk -v var="$1" '$5 == var'

入力ファイル、ログファイルを変数にして、スクリプトで$ 1を使用してからscript logfile。通常、これを行う正しい方法は何ですか?私はbashスクリプトに最初に触れたので、平均だと言います。

私が持っている2つの問題は、最初の最初のスクリプト(つまりログファイル)の$ 1が、私がawkにパイプする2番目のスクリプト(つまり最初のスクリプトの出力番号)の$ 1とは異なります。第二に、xargs -n1bashスクリプトで利用可能な対応するエントリが見つかりません。

ベストアンサー1

2番目はawk2つの入力を順番に読み込みます。最初からパイプされた出力を読み取り、ファイルawk自体からパイプされた出力を読み取ります。 2番目の入力の始まりを識別する1つの方法はNR窒素現在の投入量全履歴)が一致しなくなりましたFNR(現在Fileのレコード番号)。-FILE arg は、awkスレーブにstdin(経由で)通知することを意味します。管路、この場合)。

awk '$6=="H"{print $5}' "$1" |
awk 'NR==FNR{k[$1];next}
     $5 in k{print}' - "$1"

2番目の入力を識別する上記の方法は一般的に使用されていますが、最初の入力から何も読み取らないと予想/希望通りに動作しません。このタスクの要件については、最初の入力が何も提供しなくても構いません。ロジックは、インデックス値のリストをNR=FNR作成する場所(たとえば、デフォルトファイルなど)を決して通過しませんが、これを使用して何もしません。したがって、スクリプトは空の入力にパイプされますが、これは単なる混乱によるものです。特定のロジックが副作用として使用されます。k$1

gawkただし、GNU awk()には現在のファイル/パイプを決定する安定した方法があります。コマンドライン引数には特別なバリエーションがありますFILE"...var=value 型の引数は var 変数に値を代入します。これはファイルをまったく指定しません。"- 望むより:その他のコマンドラインパラメータ これらの配置変数=値argsが重要です - 特定のファイルに必要な値はコマンドラインに配置する必要があります今後関連ファイル – フォローアップ変数=値awk古いファイル/パイプを完全に読み取るまでは適用されません。

ここにいる変数=値バージョン。

gawk '$6=="H"{print $5}' "$1" |
gawk 'fn==1{k[$1];next}
      $5 in k{print}' fn=1 - fn=2 "$1"

出力(両方のスクリプトバージョンと同じ)

a b c d 31 1
a b c d 31 H
a b c d 31 2
a b c d 33 1
a b c d 33 H
a b c d 33 2

おすすめ記事