জেকিউ ব্যবহার করে ভেরিয়েবলগুলিতে বাশনে JSON অ্যারে


19

আমি এর মতো জেএসওএন অ্যারে পেয়েছি:

{
  "SITE_DATA": {
    "URL": "example.com",
    "AUTHOR": "John Doe",
    "CREATED": "10/22/2017"
  }
}

আমি jq ব্যবহার করে এই অ্যারেটির পুনরাবৃত্তি করতে দেখছি যাতে আমি প্রতিটি আইটেমের কীটি ভেরিয়েবল নাম এবং মান হিসাবে এটির মান হিসাবে সেট করতে পারি।

উদাহরণ:

  • Url = "example.com"
  • লেখক = "জন দো"
  • তৈরি হয়েছে = "10/22/2017"

আমি এখন পর্যন্ত যা পেয়েছি তা অ্যারে দিয়ে পুনরাবৃত্তি করেছে তবে একটি স্ট্রিং তৈরি করে:

constants=$(cat ${1} | jq '.SITE_DATA' | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]")

কোন ফলাফল:

URL=example.com
AUTHOR=John Doe
CREATED=10/22/2017

আমি স্ক্রিপ্টে আরও এই ভেরিয়েবলগুলি ব্যবহার করতে চাইছি:

echo ${URL}

তবে এই মুহুর্তে একটি খালি আউটপুট প্রতিধ্বনি করে। আমি অনুমান করছি যে evalসেখানে আমার একটি বা কিছু প্রয়োজন তবে এটিতে আমার আঙুল লাগবে না।

উত্তর:


29

আপনার আসল সংস্করণটি evalসক্ষম হতে যাচ্ছে না কারণ লেখকের নামটিতে ফাঁকা স্থান রয়েছে - এটি Doeএনভায়রনমেন্ট ভেরিয়েবল AUTHORসেট করে একটি কমান্ড চালানো হিসাবে ব্যাখ্যা করা হবে John। কার্যত কখনও jqনিজেকে পাইপ করার প্রয়োজন নেই - অভ্যন্তরীণ পাইপিং এবং ডেটাফ্লো একসাথে বিভিন্ন ফিল্টার সংযোগ করতে পারে।

আপনি জেকিউ প্রোগ্রামের অনেক সহজ সংস্করণ তৈরি করতে পারেন:

jq -r '.SITE_DATA | to_entries | .[] | .key + "=\"" + .value + "\""'

কোন ফলাফল:

URL="example.com"
AUTHOR="John Doe"
CREATED="10/22/2017"

এর কোনও প্রয়োজন নেই map: .[]বাকি পাইপলাইনটি অ্যারের মধ্যে প্রতিটি বস্তুকে পৃথক আইটেম হিসাবে গ্রহণের সাথে ডিল করে , তাই শেষের পরে সমস্ত কিছু |পৃথকভাবে প্রতিটিটিতে প্রয়োগ করা হয়। শেষে, আমরা কেবলমাত্র +ভ্যালু শেল অ্যাসাইনমেন্ট স্ট্রিংটিকে সাধারণ কাঠামোর সাথে মিলিত করি , মান সহ চারটি কোট সহ।

সমস্ত পাইপগুলি এখানে গুরুত্বপূর্ণ - এগুলি ব্যতীত আপনি মোটামুটি অস্বাস্থ্যকর ত্রুটি বার্তা পান, যেখানে প্রোগ্রামের অংশগুলি আলাদা আলাদা প্রসঙ্গে মূল্যায়ন করা হয়।

এই স্ট্রিং evalদীর্ঘ অক্ষর হিসেবে সক্ষম `, $, NEWLINE এবং নাল তথ্য প্রদর্শিত না:

eval "$(jq -r '.SITE_DATA | to_entries | .[] | .key + "=\"" + .value + "\""' < data.json)"
echo "$AUTHOR"

হিসাবে ব্যবহার করার সময় eval, সতর্কতা অবলম্বন করুন আপনি যে ডেটা পেয়ে যাচ্ছেন তাতে বিশ্বাস রাখুন, কারণ এটি দূষিত বা কেবল অপ্রত্যাশিত ফর্ম্যাটে জিনিসগুলি খুব ভুল হতে পারে go


13

@ মিশেল হোমারের উত্তরের ভিত্তিতে আপনি evalকোনও সহযোগী অ্যারেতে ডেটা পড়ে পুরোপুরি সম্ভাব্য-অনিরাপদ এড়াতে পারবেন ।

উদাহরণস্বরূপ, যদি আপনার JSON ডেটা কল করা কোনও ফাইলে থাকে file.json:

#!/bin/bash

typeset -A myarray

while IFS== read -r key value; do
    myarray["$key"]="$value"
done < <(jq -r '.SITE_DATA | to_entries | .[] | .key + "=" + .value ' file.json)

# show the array definition
typeset -p myarray

# make use of the array variables
echo "URL = '${myarray[URL]}'"
echo "CREATED = '${myarray[CREATED]}'"
echo "AUTHOR = '${myarray[URL]}'"

আউটপুট:

$ ./read-into-array.sh 
declare -A myarray=([CREATED]="10/22/2017" [AUTHOR]="John Doe" [URL]="example.com" )
URL = 'example.com'
CREATED = '10/22/2017'
AUTHOR = 'example.com'

1
আপনি অ্যাসাইনমেন্টটি একা সাথে পরোক্ষভাবে করতে পারেন declare -- “$key=$value”এবং $AUTHORকোনও অ্যারে ছাড়াই মূলর মতো কাজ করতে পারেন । এটি এখনও স্পষ্টর চেয়ে নিরাপদ, যদিও পরিবর্তন PATHবা কোনও কিছু এখনও এই সংস্করণটির তুলনায় এত কম সম্ভব।
মাইকেল হোমার

1
হ্যাঁ, অ্যারে ভেরিয়েবলগুলি আপনার পছন্দসই পাত্রে পৃথকভাবে বিচ্ছিন্ন করে - দুর্ঘটনাক্রমে / দূষিতভাবে গুরুত্বপূর্ণ পরিবেশের ভেরিয়েবলগুলির সাথে বিশৃঙ্খলার কোনও সম্ভাবনা নেই। declare --অনুমোদিত ভেরিয়েবল নামের তালিকার সাথে $ কী তুলনা করে আপনি আপনার সংস্করণটি সুরক্ষিত করতে পারেন ।
ক্যাস

1

কেবল উপলব্ধি হয়েছি যে আমি ফলাফলগুলি লুপ করতে এবং প্রতিটি পুনরাবৃত্তিটি ব্যাখ্যা করতে পারি:

constants=$(cat ${1} | jq '.SITE_DATA' | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]")

for key in ${constants}; do
  eval ${key}
done

আমাকে করতে অনুমতি দেয়:

echo ${AUTHOR}
# outputs John Doe

0

আমি সত্যিই @ মিশেল পরামর্শটি পছন্দ করি। কখনও কখনও, আপনি BASH ব্যবহার করে সেই নির্দিষ্ট সার্ভারে কোনও কার্য সম্পাদন করতে কেবল কিছু ভেরিয়েবলের মান বের করতে পারেন। সুতরাং, পছন্দসই ভেরিয়েবলগুলি জানা আছে। এই পদ্ধতির সাহায্যে চলমান প্রতি ভ্যারিয়েবলের মান নির্ধারণ করতে বা একাধিক ভেরিয়েবলের সাথে রিড স্টেটমেন্ট ব্যবহার করা বা একাধিক ভেরিয়েবলের সাথে পঠন বিবৃতি ব্যবহার করা বা একাধিক কলকে এড়ানো বা একাধিক কলগুলি এটিকে ব্যবহার করার উপায় যা মান ভরাট হতে পারে (এটি আমার সমস্যা ছিল)

আমার আগের পদ্ধতির যে নেতৃত্ব একটি মান স্থানান্তর ত্রুটি যদি .svID [] .ID = "" (হতে হবে SV পাবেন slotID মান

-rd '\n' getInfo sv slotID <<< $(jq -r '(.infoCMD // "no info"), (.svID[].ID // "none"), (._id // "eeeeee")' <<< $data)

আপনি যদি কার্ল ব্যবহার করে অবজেক্টটি ডাউনলোড করেন তবে ডেটা অ্যারে থেকে এক্সট্রাক্ট ডেটা হিসাবে বন্ধুত্বপূর্ণ নামের কিছু ভেরিয়েবলের নামকরণের জন্য আমার পদ্ধতিটি এখানে

ইভাল এবং ফিল্টার ব্যবহার করা এক লাইনের সাহায্যে সমস্যার সমাধান করবে এবং পছন্দসই নামের সাথে ভেরিয়েবল তৈরি করবে

eval "$(jq -r '.[0] | {varNameExactasJson, renamedVar1: .var1toBeRenamed, varfromArray: .array[0].var, varValueFilter: (.array[0].textVar|ascii_downcase)} | to_entries | .[] | .key + "=\"" + (.value | tostring) + "\""' <<< /path/to/file/with/object )"  

এই ক্ষেত্রে সুবিধাটি হ'ল এটি প্রথম ধাপে সমস্ত পছন্দসই ভেরিয়েবলকে ফিল্টার করবে, নাম পরিবর্তন করবে, ফর্ম্যাট করবে। সেখানে আছে তা পর্যবেক্ষণ করুন। [0] | এটি যদি খুব সাধারণ হয় তবে উত্সটি যদি কোনও জিইএস টি ব্যবহার করে কোনও রেস্ট্রুল এপিআই সার্ভার থেকে থাকে, প্রতিক্রিয়া ডেটা হিসাবে:

[{"varNameExactasJson":"this value", "var1toBeRenamed: 1500, ....}]

যদি আপনার ডেটা কোনও অ্যারের থেকে না হয়, যেমন। একটি বিষয় যেমন:

{"varNameExactasJson":"this value", "var1toBeRenamed: 1500, ....}

শুধু প্রাথমিক সূচকটি সরিয়ে ফেলুন:

eval "$(jq -r '{varNameExactasJson, renamedVar1: .var1toBeRenamed, varfromArray: .array[0].var, varValueFilter: (.array[0].textVar|ascii_downcase)} | to_entries | .[] | .key + "=\"" + (.value | tostring) + "\""' <<< /path/to/file/with/object )"  

এটি একটি পুরানো প্রশ্ন, তবে আমি ভাগ করে নিতে অনুভব করেছি, কারণ এটি খুঁজে পাওয়া শক্ত ছিল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.