jq出力でスペースを区切らないでください。

jq出力でスペースを区切らないでください。

私はjqを使って単語の配列をJavaプログラムのパラメータに変換しています。

それはまるで

arguments=$(jq '.nameField | "-i " + "\"" + . + "\""' file.json)

java .... $arguments  <-- No quotes wrapped around arguments.

期待される出力:Java は で読まなければならず-i "Name 1" -i "Name 2"、 " Name 1" は完全なパラメータで読まなければなりません。

出力を受信:Javaは読み込み中および"Nameそれぞれエラーを発生させます。1""Name2"

「名前1」を単一のエンティティとして扱いたいです。

答え1

パラメータを配列に保存する必要があります。

.nameField値に改行文字が含まれていないとします。

readarray -t arguments < <(jq -r '.nameField | "-i", .' file.json)

java ... "${arguments[@]}"

このjqコマンドは「-i」を実行し、それぞれの名前を別々の行に配置し、そのreadarray行を配列として読み込みます。

バラよりコマンドを変数に入れようとしましたが、複雑な場合は常に失敗します!


コードが正しく機能するためには必要ですeval java ... $argumentsが、一般的にはお勧めできません。

答え2

この試み:

eval "arguments=($(jq -r '.nameField | ["-i", .] | @sh' file.json))"
java ... "${arguments[@]}"

答え3

入力JSONファイルの最上位レベルに、配列ではなく次のような複数のオブジェクトが含まれているとします。

{"nameField":"Name 1"}
{"nameField":"Name 2"}
{"nameField":"Name 3"}
{"nameField":"Name 4"}
{"nameField":"Name 5"}

...そしてnameField値に新しい行(またはNUL)が含まれていない場合は、jqすべての値を抽出し、次を使用してbash配列を設定しますarguments

arguments=()
while IFS= read -r name; do
    arguments+=( -i "$name" )
done < <( jq -r '.nameField' file.json )

その後、配列を拡張するときにJavaコードを呼び出します。

java ... "${arguments[@]}"

拡張は"${arguments[@]}"、ここに示すように正確に引用する必要があります。それ以外の場合、シェルは各値に含まれるスペースまたはタブから各値を分割します(そして結果の文字列に対してファイル名のグロービングを実行します)。

JSON文字列をJavaコードに渡すには(質問ではわかりません)、-rこれを行います。これにより、パラメータにリテラル二重引用符を含むパラメータが作成されたかのように、文字列がコマンドに渡さjqれます。これは、値に挿入された改行またはNULを含めることができないという制限を排除します(それぞれおよびエンコードされています)。java-i '"Name 1"' -i '"Name 2"'nameField\n\u0000

関連情報