Jqを使用してjson配列内のすべてのjsonオブジェクトに対してbashコマンドを実行するにはどうすればよいですか?これまでのところ私はこれを持っています:
cat credentials.json | jq -r '.[] | .user, .date, .email' | mycommand -u {user} -d {date} -e {email}
これはうまくいかないようです。 json配列からコマンドにパラメーターを取得するにはどうすればよいですか?
私のjsonファイルは次のようになります。
[
"user": "danielrvt",
"date": "11/10/1988",
"email": "[email protected]",
...
]
最善の策は、おそらく各レコードをTSV形式などで出力し、それをシェルループから読み取ることです。
jq -r '.[]|[.user, .date, .email] | @tsv' |
while IFS=$'\t' read -r user date email; do
mycommand -u "$user" -d "$date" -e "$email"
done
jq
自体には、フィルター内から外部コマンドを実行するsystem
呼び出しのようなものはありませんが、 それらは処理中です のようです。
実行するコマンドをjq
に出力させることができます。
.[] | "mycommand \(.user|@sh) \(.date|@sh) \(.email|@sh)"
次に実行します。何かのようなもの
bash <(jq -r '.[] | "mycommand \(.user|@sh) \(.date|@sh) \(.email|@sh)"' foo)
Xargsの場合:
curl localhost:8082/connectors | jq .[] | xargs -L1 -I'{}' curl -XDELETE 'localhost:8082/connectors/{}'
または同等に、その最初のcurlの出力を表示するには:
echo '["quickstart-file-sink4","quickstart-file-source","quickstart-file-sink","quickstart-file-sink2","quickstart-file-sink3","quickstart-file-source2"]' | jq .[] | xargs -L1 -I'{}' curl -XDELETE 'localhost:8082/connectors/{}'
jq .[]
は、1レベルの包含を取り除き、リストがアイテムごとに1行として出力されるようにします。
xargs -L1
一度に1行を処理します
xargs -I'{}'
は、文字列{}
は、次のコマンドを呼び出すときに入力行に置き換えられます。
xargs
は、本質的にはシェルのマップ演算子です。
最近渡したかった比較的複雑な引数セットのために、xargsがあまり役に立たないという同じ問題に出会いました。したがって、jqにsh
フィルター(およびそのフレンド)を実装しました。私はまだドキュメントとテストを書く十分な時間がないので、公式のコードベースの一部になるためのPRをまだ作成していません。そのため、今ではこのバージョンを自分でコンパイルしたいと思っている人だけのためになっています。
@chepnerからの回答に基づいた別のバリエーションがあります。
echo "$config" | jq -c '.[]' |
while IFS=$"\n" read -r c; do
echo "start"
Host=$(echo "$c" | jq -r '.Host')
echo $Host
echo "end"
done
Jqの-cオプションを使用して「コンパクトな」jsonを出力したため、すべてが1行になります。
IFS=$"\n"
と組み合わせて、入力jsonの配列内の各項目をループし、やりたいことを行うことができました。
したがって、の入力で
[
{
"Host": "Host1",
"settings": {}
},
{
"Host": "Host1",
"settings": {}
}
]
出力は
start
Host1
end
start
Host2
end