将bash变量传递给jq选择

时间:2016-10-13 17:28:55

标签: json bash environment-variables jq

我编写了一个脚本来从file.json检索某些值。如果我将值提供给jq select,但该变量似乎不起作用(或者我不知道如何使用它),它就有效。

#!/bin/sh

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

EMAILID=myemail@hotmail.com

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

8 个答案:

答案 0 :(得分:86)

考虑将shell变量(EMAILID)作为jq变量传递(为了说明,这里也是EMAILID):

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

后记

对于记录,另一种可能性是使用jq的env函数来访问环境变量。例如,考虑这个bash命令序列:

EMAILID=foo@bar.com  # not exported
EMAILID="$EMAILID" jq -n 'env.EMAILID'

输出是JSON字符串:

"foo@bar.com"

答案 1 :(得分:11)

这是一个引用问题,您需要:

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

如果您使用单引号来分隔主字符串,那么shell将逐字地获取$EMAILID

"双引号"每个包含空格/元字符和每个扩展的文字:"$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

答案 2 :(得分:7)

我通过转义内部双引号来解决这个问题

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

答案 3 :(得分:3)

无关紧要,但我仍会放在这里, 出于其他实际目的,shell变量可以用作-

<root>
<p>Agarwal v Johnson (1979) 25 C3d 932, overruled on other grounds in White v Ultramar, Inc. (1999) 21 C4th 563</p>
<p>Advantacare Health Partners (1994) US Dist Lexis</p>
<p>Alexander v Gardner-Denver Co. (1974) 415 US 36, 94 S Ct 1011</p>
</root>

答案 4 :(得分:2)

另一种实现此目的的方法是使用jq“--arg”标志。 使用原始示例:

#!/bin/sh

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

EMAILID=myemail@hotmail.com

# 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

答案 5 :(得分:1)

将其张贴在这里可能会帮助其他人。以字符串形式,可能需要将引号传递给jq。要对jq执行以下操作:

.items[] | select(.name=="string")

你可以做的

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

基本上转义引号并将其传递给jq

答案 6 :(得分:1)

Jq现在有了访问环境变量的更好方法,您可以使用env.EMAILI:

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

答案 7 :(得分:0)

抱歉,稍后再回复。但这对我有用。

export K8S_public_load_balancer_url="$(kubectl get services -n ${TENANT}-production -o wide | grep "ingress-nginx-internal$" | awk '{print $4}')"

现在我能够获取并将变量的内容传递给jq

export TF_VAR_public_load_balancer_url="$(aws elbv2 describe-load-balancers --region eu-west-1 | jq -r '.LoadBalancers[] | select (.DNSName == "'$K8S_public_load_balancer_url'") | .LoadBalancerArn')"

在我的情况下,我需要使用双引号和双引号来访问变量值。

干杯。