web-dev-qa-db-ja.com

bash変数をjq selectに渡す

file.jsonから特定の値を取得するスクリプトを作成しました。 jq selectに値を指定すると機能しますが、変数が機能しないようです(または、使用方法がわかりません)。

#!/bin/sh

#this works ***
projectID=$(cat file.json | jq -r '.resource[] | select(.username=="[email protected]") | .id')
echo "$projectID"

[email protected]

#this does not work *** no value is printed
projectID=$(cat file.json | jq -r '.resource[] | select(.username=="$EMAILID") | .id')
echo "$projectID"
52
asidd

シェル変数(EMAILID)をjq変数として渡すことも検討してください(ここでは、説明のためにEMAILIDも使用しています)。

   projectID=$(cat file.json | 
     jq -r --arg EMAILID "$EMAILID" '
        .resource[]
        | select(.username==$EMAILID) 
        | .id')

追記

レコードについては、jqのenv関数を使用して環境変数にアクセスすることもできます。たとえば、次のbashコマンドのシーケンスを考えます。

[email protected]  # not exported
EMAILID="$EMAILID" jq -n 'env.EMAILID'

出力はJSON文字列です。

"[email protected]"
87
peak

それは引用の問題です、あなたは必要です:

projectID=$(
  cat file.json | jq -r ".resource[] | select(.username=='$EMAILID') | .id"
)

単一引用符を入れてメイン文字列を区切ると、シェルは$EMAILIDをそのまま受け取ります。

スペース/メタ文字とevery展開を含むすべてのリテラルを「二重引用符」:"$var""$(command "$var")""${array[@]}""a & b"。コードまたはリテラル'single quotes'$'s: 'Costs $5 US'にはssh Host 'echo "$HOSTNAME"'を使用します。見る
http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words

10
Gilles Quenot

内側の二重引用符をエスケープすることでこの問題を解決しました

projectID=$(cat file.json | jq -r ".resource[] | select(.username==\"$EMAILID\") | .id")
7
asidd

これを実現する別の方法は、jq "--arg"フラグを使用することです。元の例を使用:

#!/bin/sh

#this works ***
projectID=$(cat file.json | jq -r '.resource[] | 
select(.username=="[email protected]") | .id')
echo "$projectID"

[email protected]

# Use --arg to pass the variable to jq. This should work:
projectID=$(cat file.json | jq --arg EMAILID $EMAILID -r '.resource[] 
| select(.username=="$EMAILID") | .id')
echo "$projectID"

ここを参照してください、私はこの解決策を見つけました: https://github.com/stedolan/jq/issues/626

2
Andrew Lockhart