単一の「jq」コマンドが別のファイルに書き込まれます。

単一の「jq」コマンドが別のファイルに書き込まれます。

JSONログファイルがありますtest.log

{"type":"1","fname":"AAA","lname":"bbb" }    
{"type":"2","state":"gujarat" }     
{"type":"3","city":"ahmedabad" }    
{"type":"3","city":"rajkot" }   
{"type":"1","fname":"ccc","lname":"ddd" }  

次のコマンドを実行します。

cat test.log | jq -c "select(.type==\"1\")|{fname:.fname}" > type_1.txt     
cat test.log | jq -c "select(.type==\"3\")|{city:.city}" > type_3.txt  

単一のコマンドでjq複数の出力ファイルを生成できますか?

ファイルに対してjqコマンドを一度だけ実行しtest.log、プロジェクトタイプごとに1つの出力ファイルを生成したいと思います。

答え1

~によるとマニュアルのIO部分バージョン1.5以降、jqは標準出力にのみ書き込むことができ、デバッグメッセージをstderr

jqを何度も実行したくない場合test.log(たとえば、大容量ファイルであるため)、次のようにすることができます。

jq -c '(select(.type=="1") | {fname:.fname}), (select(.type=="3") | {city:.city})' test.log > temp
# The file 'temp' contains one entry per line.
grep '^{"fname"' temp > type_1.txt
grep '^{"city"' temp > type_3.txt   
rm temp

答え2

を使用する代わりに、jq他のJSON対応プロセッサであるMiller(mlr)を使用してください。

mlr --json put -q '
    $type == 1 { emit >"type_1.txt", { "fname": $fname } }
    $type == 3 { emit >"type_3.txt", { "city":  $city  } }' file

isの場合、fnameキーとファイルに対応する値を含むJSONオブジェクトを印刷し、そのキーのエントリも処理します。type_1.txttype1type 3city

ファイルtype_1.txttype_3.txt存在する場合、このコマンドは新しいデータを書き込む前に切り捨てられます(空になります)。

例を実行してください:

$ mlr --json put -q '$type == 1 { emit >"type_1.txt", { "fname": $fname } }; $type == 3 { emit >"type_3.txt", { "city":  $city  } }' file
$ cat type_1.txt
{ "fname": "AAA" }
{ "fname": "ccc" }
$ cat type_3.txt
{ "city": "ahmedabad" }
{ "city": "rajkot" }

答え3

jqstdout(またはstderr)のみが記録されるため、ストリームを別のログファイルに分割するには別のプログラムが必要です。
まずjs@nwk のコマンドとしてログファイルフィールドの強化を使用します。

jq -c '(select(.type=="1") | {"logfile":.type},{fname:.fname}),
       (select(.type=="3") | {"logfile":.type},{city:.city})' test.log

この出力をパイプで接続すると、awkファイル名を取得できます。

jq -c '(select(.type=="1") | {"logfile":.type},{fname:.fname}),
       (select(.type=="3") | {"logfile":.type},{city:.city})' test.log |
       awk -F"\"" 'BEGIN {FPAT="[^{}:\"]+" } 
            $1=="logfile" {lf="type_"$2".txt"; next}
            {print >> lf}'

答え4

パーティーに少し遅れました。この問題を完全に元に戻すことができます。スクリプトで実行したときに他のファイルに書き込む方法を尋ねる代わりに、別のファイルに書き込む出力をjq生成できます。jq

例は次のとおりです。

jq -r \
  $' recurse( .children[] ) | 
  select( (.type="comment") and (.text != null) ) |
  "echo \'" + .text + "\' >> " + .author + ".txt" ' < file.json

実行すると、次のような出力が生成されます。

echo '<p>Nice! Definitely let me know.</p>' >> user_1.txt
echo '<p>I agree.</p>' >> user_2.txt

その後、この出力をスクリプトとして実行して別々のファイルを生成できます。jq現在、シェル以外の依存関係もなく、パイプもなく、追加のツールも必要ありません。$'プレフィックスと'サフィックスはステートメント\'内でエスケープできますecho

関連情報