awkスクリプトから複数の圧縮ファイルを読む

awkスクリプトから複数の圧縮ファイルを読む

というawkスクリプトがありますtext_processing.awk。さらに処理するには、名前などの複数のzipファイルをこのスクリプトに01JAN21.txt.gz渡す必要があります。02JAN21.txt.gz出力ファイルは入力ファイルから日付を取得して名前を指定しますresult_01JAN21.txt

このファイルは圧縮されています。

まず、次のコマンドを使用してファイルから実行しようとしました。

zcat 01JAN21.txt.gz | awk -f text_processing.awk -

しかし、私の出力ファイルの名前は指定されていません。このコマンドはファイルを開いてスクリプトにパイプするだけで、私のスクリプトは以下のように入力ファイル名から日付を抽出するためだと思います。

BEGIN{ 
  FS = ";" 
  input_file = ARGV[1] 
  sub(/\.txt\.gz/, "", input_file) 
  output = "result_" input_file ".txt 
}

修正方法のご案内をいただきありがとうございます。一度に複数のファイルを渡すので、awkスクリプトで出力ファイルの名前を変更したいと思います。

ベストアンサー1

現在のディレクトリの名前が一致するすべてのファイルを処理しているとします*.txt.gz。名前を変数として渡しawk、圧縮されていないデータをストリーミングします。

for name in *.txt.gz; do
    gzip -c -d -- "$name" |
    awk -v name="$name" -f text_processing.awk
done

awkコードはname変数を使用して出力ファイル名を計算します。

または、シェルスクリプトに使用する明示的な出力ファイル名を指定します。

for name in *.txt.gz; do
    gzip -c -d -- "$name" |
    awk -v outname="result_${name%.gz}" -f text_processing.awk
done

result_${name%.gz}文字列はプレフィックスが削除され、追加されたソースファイルの名前になります。その後、コードを書くために使用されます。.gzresult_awkoutname

明らかにawk、コードが単一の出力ファイルにのみ書き込む場合は、awkコードをさらに簡素化して標準出力として印刷できます。次に、シェルから出力をリダイレクトします。

for name in *.txt.gz; do
    gzip -c -d -- "$name" |
    awk -f text_processing.awk >"result_${name%.gz}"
done

コメントで要求された追加資料:並列にawkコマンドを実行する。

この目的のために、xargsユーティリティが非標準オプション-0(Nulで終わるデータを読み取る)、-r(入力がないときに与えられたコマンドを実行しない)、および-P(並列ジョブの実行)をサポートしているとします。

print '%s\0' *.txt.gz |
xargs -0r -P 4 -I {} sh -c '
    gzip -c -d -- "$1" |
    awk -f text_processing.awk >"result_${1%.gz}"' sh {}

これにより、4つのファイルのgzip+パイプラインが同時に実行されます。生成中のコマンドをインポートして表示するために、ユーティリティにオプションが追加されawkました。-txargs

おすすめ記事