चयन करने के लिए bash चर पासिंग बैश


112

मैंने कुछ मान प्राप्त करने के लिए एक स्क्रिप्ट लिखी है 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"

एक संबंधित मुद्दा: jash फ़िल्टर करने के लिए बैश वैरिएबल को थोड़ा अलग सिंटैक्स jq -r --arg var "$var" '.[$var]' stackoverflow.com/questions/34745451/…
enharmonic

जवाबों:


176

गो चर (EMAILID) को जाक चर के रूप में पास करने पर विचार करें (यहाँ भी EMAILID, उदाहरण के लिए:)

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

परिशिष्ट भाग

रिकॉर्ड के लिए, envपर्यावरण चर तक पहुँचने के लिए jq के फ़ंक्शन का उपयोग करने की एक और संभावना होगी । उदाहरण के लिए, बैश कमांड के इस क्रम पर विचार करें:

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

आउटपुट एक JSON स्ट्रिंग है:

"foo@bar.com"

4
यह केवल 100% -safe जवाब है; यह jqमान का उपयोग करके फ़िल्टर को ठीक से बनाने देता है, बजाय इसके bashकि स्ट्रिंग को बनाने के लिए उपयोग jqकरता है जो फ़िल्टर के रूप में व्याख्या करता है। (विचार करें कि क्या होता है यदि मान EMAILIDमें a )।)
चेपनर

3
धन्यवाद शिखर। आपका प्रदान किया गया समाधान उचित प्रतिक्रिया है जिसकी मुझे तलाश थी। हाँ यह काम करता है।
asidd

मेरा उपयोग मामला, यह काम करता है! function n2 { termux-contact-list |jq -r --arg v1 "$1" '.[] | select(.name==$v1)|.number' }कॉलिंग:n2 Name1
टिमो

2
fyi, jq का envफ़ंक्शन jq 1.4 और 1.5+ के बीच बदल जाता है, इसलिए env.EMAILID(इस उत्तर के उदाहरण में) jq 1.4 में काम नहीं करता है, इस प्रकार --arg EMAILID "$EMAILID"यदि आप jq 1.4 का उपयोग करने की आवश्यकता है तो निर्माण का उपयोग करने की अनुशंसा करते हैं । उम्मीद है की यह मदद करेगा; बस मुझे एक दिन लग गया + अपने लिए यह पता लगाने के लिए;)
m0j0hn

3
उपयोग किए गए तर्क --argको तार के रूप में पारित किया जाएगा। यदि आप एक अलग JSON प्रकार का डेटा पास करना चाहते हैं, तो उपयोग करें --argjson, जो स्ट्रिंग को JSON, जैसे,--argjson myObj '{"a": [1, 2]}'
BallpointBen

25

मैंने आंतरिक दोहरे उद्धरणों से बचकर इस मुद्दे को हल किया

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

मैं इस का उपयोग कर रहा है क्योंकि --arg साथ अच्छा नहीं चलता है-c
दिमित्रिस Moraitidis

9

यह एक उद्धरण मुद्दा है, आप की जरूरत है:

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

यदि आप मुख्य स्ट्रिंग को सीमांकित करने के लिए एकल उद्धरण डालते हैं , तो शेल लेता है$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 देखें


मेरे मामले में त्रुटि के साथ ही, अगर सभी उद्धरणों का उपयोग नहीं कर रहे हैं, तो समान termux-contact-list |jq -r '.[] | select(.name=='$1')|.number':। परिणाम:jq Compile error
टिमो

6
मुझे यकीन नहीं है कि इस टिप्पणी को कितनी बार वोट दिया गया है; हां, दोहरे उद्धरण परिवर्तनशील विस्तार की अनुमति देते हैं, लेकिन jqएकल उद्धरण पसंद नहीं करते:jq: error: syntax error, unexpected INVALID_CHARACTER (Unix shell quoting issues?)
jdelman

यदि आपका इनपुट नियमित जसन है, तो इसके मूल्य दोहरे (सिंगल नहीं) होंगे। क्या काम करता है: jq के पूरे arg के लिए दोहरे उद्धरण चिह्नों का उपयोग करना और (`` के साथ) भागने का कोई भी दोहरा उद्धरण जैसे @asid ने उत्तर दिया।
गुस्कु

6

इसे यहां पोस्ट करना क्योंकि इससे दूसरों को मदद मिल सकती है। स्ट्रिंग में, उद्धरण को jq में पास करना आवश्यक हो सकता है। Jq के साथ निम्नलिखित करने के लिए:

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

आप कर सकते हैं

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

अनिवार्य रूप से उद्धरणों से बचकर और इसे jq पर पास करना


अच्छी तरह से काम। त्वरित समाधान की तलाश में किसी के लिए भी जटिल नहीं है।
मो-गंग

4

इसे पूरा करने का एक और तरीका है, "- गर्ग" झंडे के साथ। मूल उदाहरण का उपयोग करना:

#!/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


2

मुझे पता है कि जवाब देने के लिए थोड़ा बाद में, क्षमा करें। लेकिन वह मेरे लिए काम करता है।

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')"

मेरे मामले में मुझे चर मान तक पहुंचने के लिए दोहरे उद्धरण और उद्धरण का उपयोग करने की आवश्यकता थी।

चीयर्स।


1

Jq के पास अब पर्यावरण चर को बेहतर बनाने के लिए, आप env.EMAILI का उपयोग कर सकते हैं:

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

0

थोड़ा असंबंधित, लेकिन मैं अभी भी इसे यहां डालूंगा, अन्य व्यावहारिक उद्देश्यों के लिए शेल चर का उपयोग किया जा सकता है -

value=10
jq  '."key" = "'"$value"'"' file.json
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.