জিকিউ সহ অভ্যন্তরীণ অ্যারেতে মানের উপর ভিত্তি করে অবজেক্টগুলির একটি অ্যারে ফিল্টার করবেন কীভাবে?


239

এই ইনপুট দেওয়া:

[
  {
    "Id": "cb94e7a42732b598ad18a8f27454a886c1aa8bbba6167646d8f064cd86191e2b",
    "Names": [
      "condescending_jones",
      "loving_hoover"
    ]
  },
  {
    "Id": "186db739b7509eb0114a09e14bcd16bf637019860d23c4fc20e98cbe068b55aa",
    "Names": [
      "foo_data"
    ]
  },
  {
    "Id": "a4b7e6f5752d8dcb906a5901f7ab82e403b9dff4eaaeebea767a04bac4aada19",
    "Names": [
      "jovial_wozniak"
    ]
  },
  {
    "Id": "76b71c496556912012c20dc3cbd37a54a1f05bffad3d5e92466900a003fbb623",
    "Names": [
      "bar_data"
    ]
  }
]

আমি একটি ফিল্টার গঠন করা চেষ্টা করছি jq যে আয় আছে এমন সমস্ত বস্তু Idগুলি করে না ভেতরের মধ্যে "ডেটা" থাকতেই Namesএরে, আউটপুট সম্পর্কে newline বিভাজিত হয়ে পড়ে থাকে। উপরের ডেটার জন্য, আউটপুটটি আমি চাই like

cb94e7a42732b598ad18a8f27454a886c1aa8bbba6167646d8f064cd86191e2b
a4b7e6f5752d8dcb906a5901f7ab82e403b9dff4eaaeebea767a04bac4aada19

আমি মনে করি আমি এর সাথে কিছুটা ঘনিষ্ঠ:

(. - select(.Names[] contains("data"))) | .[] .Id

তবে selectফিল্টারটি সঠিক নয় এবং এটি সংকলন করে না (পাওয়া error: syntax error, unexpected IDENT)।

উত্তর:


372

খুব কাছে! আপনার selectঅভিব্যক্তিতে আপনাকে |আগে পাইপ ( ) ব্যবহার করতে হবে contains

এই ফিল্টারটি প্রত্যাশিত আউটপুট উত্পাদন করে।

. - map(select(.Names[] | contains ("data"))) | .[] .Id

Jq Cookbook সিনট্যাক্স একটি উদাহরণ রয়েছে।

একটি কী এর বিষয়বস্তুর উপর ভিত্তি করে ফিল্টার অবজেক্টস

উদাহরণস্বরূপ, আমি কেবলমাত্র সেই জিনিসগুলি চাই যার জেনার কীটিতে "বাড়ি" রয়েছে।

$ json='[{"genre":"deep house"}, {"genre": "progressive house"}, {"genre": "dubstep"}]'
$ echo "$json" | jq -c '.[] | select(.genre | contains("house"))'
{"genre":"deep house"}
{"genre":"progressive house"}

কলিন ডি অ্যারের JSON কাঠামো কীভাবে সংরক্ষণ করবেন তা জিজ্ঞাসা করেন, যাতে চূড়ান্ত আউটপুটটি JSON অবজেক্টের স্ট্রিমের পরিবর্তে একক JSON অ্যারে হয়।

সহজ উপায় হ'ল একটি অ্যারে নির্মাণকারীতে পুরো এক্সপ্রেশনটি মোড়ানো:

$ echo "$json" | jq -c '[ .[] | select( .genre | contains("house")) ]'
[{"genre":"deep house"},{"genre":"progressive house"}]

আপনি মানচিত্রের ফাংশনটিও ব্যবহার করতে পারেন:

$ echo "$json" | jq -c 'map(select(.genre | contains("house")))'
[{"genre":"deep house"},{"genre":"progressive house"}]

মানচিত্র ইনপুট অ্যারে প্যাক করে, প্রতিটি উপাদানগুলিতে ফিল্টার প্রয়োগ করে এবং একটি নতুন অ্যারে তৈরি করে। অন্য কথায়, map(f)সমান [.[]|f]


ধন্যবাদ, দুর্দান্ত কাজ করে! আমি আসলে উদাহরণটি দেখেছি, আমি এটি আমার দৃশ্যের সাথে খাপ খাইয়ে ব্যর্থ হয়েছি :-)
অ্যাবে ভোলেকার

1
"অ্যারের জসন কাঠামো সংরক্ষণ" করার জন্য কি কোনও উপায় আছে? আমি জেনার উদাহরণটি পছন্দ করি তবে এটি দুটি "জসন লাইন" আউটপুট করে। আমি অগত্যা মানচিত্রের অংশটি বের করতে পারিনি
কলিন ডি

4
@ কলিনডি আমি হ্রাস সমাধানের সাথে সত্যিই খুশি ছিলাম না, তাই আমি এটিকে মানচিত্রের কার্যকারিতার ব্যাখ্যা দিয়ে প্রতিস্থাপন করেছি। এটা কি সাহায্য করে?
আইয়েন স্যামুয়েল ম্যাকলিন প্রবীণ

@ আইইনএলডার - যখন অনুসন্ধান শব্দটির অংশটি (এই ক্ষেত্রে বাড়িতে) পরিবর্তনশীল হয় তখন কী ঘটে? সুতরাং --args শব্দটি ব্যবহার করে বলুন। সুতরাং এতে রয়েছে ("
হাউ

@ ক্রিস ভেরিয়েবলটিকে $termএকটি স্ট্রিং হিসাবে বিবেচনা করা হবে, সুতরাং আপনার স্ট্রিং কনটেন্টেশন ব্যবহার করা উচিত:contains("hou" + $term)
আইয়েন স্যামুয়েল ম্যাকলিন এল্ডার

17

এখানে অন্য সমাধানটি যা কোনও / 2 ব্যবহার করে

map(select(any(.Names[]; contains("data"))|not)|.Id)[]

নমুনা ডেটা এবং -rবিকল্পটি এটি উত্পাদন করে

cb94e7a42732b598ad18a8f27454a886c1aa8bbba6167646d8f064cd86191e2b
a4b7e6f5752d8dcb906a5901f7ab82e403b9dff4eaaeebea767a04bac4aada19

হুবহু আমি যা খুঁজছিলাম - কেন এটি .Names[] ; contains()একটি পাইপ দিয়ে নয় আধা-কোলন দিয়ে কাজ করে .Names[] | contains()?
ম্যাট

3
আহ, এটি any(generator; condition)ফর্ম। আমি খুঁজে পেয়েছি যে ব্যবহার না করেই any()আমি select()একই ফলাফলের সাথে একাধিকবার মিলে গেলে আমার ফলাফলগুলিতে ডুপ্লিকেট দিয়ে শেষ করব ।
ম্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.