web-dev-qa-db-ja.com

jashとbashを使用して、配列内の各オブジェクトに対してコマンドを実行する

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]",
   ...
]
15
danielrvt

最善の策は、おそらく各レコードを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呼び出しのようなものはありませんが、 それらは処理中です のようです。

19
chepner

実行するコマンドをjqに出力させることができます。

.[] | "mycommand \(.user|@sh) \(.date|@sh) \(.email|@sh)"

次に実行します。何かのようなもの

bash <(jq -r '.[] | "mycommand \(.user|@sh) \(.date|@sh) \(.email|@sh)"' foo)
9
kojiro

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は、本質的にはシェルのマップ演算子です。

6
Marcin

最近渡したかった比較的複雑な引数セットのために、xargsがあまり役に立たないという同じ問題に出会いました。したがって、jqにshフィルター(およびそのフレンド)を実装しました。私はまだドキュメントとテストを書く十分な時間がないので、公式のコードベースの一部になるためのPRをまだ作成していません。そのため、今ではこのバージョンを自分でコンパイルしたいと思っている人だけのためになっています。

https://github.com/haochenx/jq/tree/sh-support

2
Haochen Xie

@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
0
Chris Gibb