YAML অ্যারেগুলিকে কীভাবে মার্জ করবেন?


122

আমি YAML এ অ্যারেগুলিকে একীভূত করতে এবং রুবির মাধ্যমে এগুলি লোড করতে চাই -

some_stuff: &some_stuff
 - a
 - b
 - c

combined_stuff:
  <<: *some_stuff
  - d
  - e
  - f

আমি সম্মিলিত অ্যারে হিসাবে চাই [a,b,c,d,e,f]

আমি ত্রুটিটি পেয়েছি: একটি ব্লক ম্যাপিং পার্স করার সময় প্রত্যাশিত কীটি পাইনি

আমি কীভাবে YAML এ অ্যারে মার্জ করব?


6
আপনি যে ভাষার সাথে অংশীকরণ করছেন তার পরিবর্তে আপনি কেন YAML এ এটি করতে চান?
প্যাট্রিক কলিন্স

7
খুব বড় ইয়ামল ফাইলটিতে নকল শুকানোর জন্য
lfender6445

4
এটি খুব খারাপ অনুশীলন। আপনার আলাদাভাবে ইয়ামল পড়া উচিত, রুবিতে অ্যারেগুলি একসাথে রাখা উচিত, তারপর এটি আবার ইয়ামলে লিখুন।
সাওয়া

80
শুকনো খারাপ অভ্যাস হতে চেষ্টা করছে কীভাবে?
ক্রাক 3 ই

13
@ পেট্রিকক্লিনস আমি এই প্রশ্নটি আমার .গিটলব-সিআইএমএল ফাইলে নকল হ্রাস করার চেষ্টা করে দেখতে পেয়েছি এবং দুর্ভাগ্যক্রমে গিটল্যাব সিআই যে
পার্সারটি

উত্তর:


45

যদি লক্ষ্যটি শেল কমান্ডগুলির একটি ক্রম চালানো হয়, আপনি নিম্নলিখিত হিসাবে এটি অর্জন করতে সক্ষম হতে পারেন:

# note: no dash before commands
some_stuff: &some_stuff |-
    a
    b
    c

combined_stuff:
  - *some_stuff
  - d
  - e
  - f

এটি সমান:

some_stuff: "a\nb\nc"

combined_stuff:
  - "a\nb\nc"
  - d
  - e
  - f

আমি এটি আমার ব্যবহার করে যাচ্ছি gitlab-ci.yml(প্রশ্নের উত্তর @ rink.attendant.6 মন্তব্যে)।


কাজের উদাহরণ যা আমরা requirements.txtগিটলাব থেকে ব্যক্তিগত রেপো সমর্থন করতে ব্যবহার করি:

.pip_git: &pip_git
- git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com".insteadOf "ssh://git@gitlab.com"
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts

test:
    image: python:3.7.3
    stage: test
    script:
        - *pip_git
        - pip install -q -r requirements_test.txt
        - python -m unittest discover tests

use the same `*pip_git` on e.g. build image...

যেখানে requirements_test.txtথাকে যেমন

-e git+ssh://git@gitlab.com/example/example.git@v0.2.2#egg=example


4
চতুর। আমি এখন এটি আমাদের বিটবকেট পাইপলাইনে ব্যবহার করছি। ধন্যবাদ
দারিওপ

* এখানে পিছনের ড্যাশ প্রয়োজন হয় না, কেবল শেষে পাইপই যথেষ্ট। * এটি একটি নিকৃষ্ট সমাধান যেহেতু যখন কাজটি খুব দীর্ঘ মাল্টি-লাইন বিবৃতিতে ব্যর্থ হয় তখন কোন আদেশটি ব্যর্থ হয়েছিল তা পরিষ্কার নয়।
মিনা লুক

4
@ মিনালুক, তুলনায় নিকৃষ্ট? বর্তমানের উত্তরগুলির মধ্যে কেবলমাত্র ইয়ামল ব্যবহার করে দুটি আইটেম একীভূত করার উপায় সরবরাহ করে না ... তাছাড়া, ওপেন সিআই / সিডিতে এটি ব্যবহার করতে ইচ্ছুক বলে প্রশ্নটিতে কিছুই নেই। অবশেষে, যখন এটি সিআই / সিডিতে ব্যবহৃত হয়, লগিং কেবল নির্দিষ্ট সিআই / সিডি নির্ভর করে, যমলের ঘোষণার উপর নয়। সুতরাং, যদি কিছু হয় তবে আপনি যে সিআই / সিডি উল্লেখ করছেন সেটি হ'ল একটি খারাপ কাজ করছেন। এই উত্তরের ইয়ামলটি বৈধ, এবং ওপির সমস্যা সমাধান করে।
জর্জি লিটাও

@ জোর্জেলিটাও আমার ধারণা আপনি বিধিগুলি একত্রিত করতে এটি ব্যবহার করেন। আপনি একটি কাজের গিটলসি উদাহরণ প্রদান করতে পারেন? আমি আপনার সমাধানের ভিত্তিতে কিছু চেষ্টা করেছি, তবে সর্বদা একটি বৈধতা ত্রুটি পাই।
নিলস

4
এটা আমার জন্য কাজ করে না। এর সাথে - আমি একটি ত্রুটি পেয়েছি, যেমন এটি কোনও তালিকা আইটেমের ভিতরে তালিকাটি toোকানোর চেষ্টা করে trying পাইপটি কীভাবে ব্যবহার করতে হয় তা আমি জানি না। ওটা কিসের জন্য ছিলো? @ ডারিওপ এটি বিবি পাইপলাইনে কীভাবে ব্যবহার করবেন?
ভিক্টর ফেরেরিরা

28

আপডেট: 2019-07-01 14:06:12

  • দ্রষ্টব্য : বিকল্প পদ্ধতির আপডেট নিয়ে এই প্রশ্নের অন্য উত্তরটি যথেষ্ট পরিমাণে সম্পাদিত হয়েছিল ।
    • আপডেট হওয়া এই উত্তরে এই উত্তরে কর্মসূচীর বিকল্পের উল্লেখ রয়েছে। এটি নীচে দেখুন বিভাগে যুক্ত করা হয়েছে ।

প্রসঙ্গ

এই পোস্টটি নিম্নলিখিত প্রসঙ্গটি ধরে:

  • অজগর 2.7
  • পাইথন ইয়ামএল পার্সার

সমস্যা

lfender6445 দুই বা ততোধিক তালিকাগুলি একটি ওয়াইএএমএল ফাইলের মধ্যে একত্রীকরণ করতে চায় এবং এই মার্জ তালিকাগুলি বিশ্লেষণের পরে একক তালিকা হিসাবে উপস্থিত হয়।

সমাধান (কার্যনির্বাহী)

ম্যাপিংগুলিতে ওয়াইএএমএল অ্যাঙ্করগুলি সরবরাহ করে এটি প্রাপ্ত হতে পারে, যেখানে পছন্দসই তালিকা ম্যাপিংয়ের শিশু উপাদান হিসাবে উপস্থিত হয়। এটির বিষয়ে সতর্কতা রয়েছে তবে ("পিটফলস" ইনফ্রা দেখুন)।

নীচের উদাহরণে আমাদের কাছে তিনটি ম্যাপিংস ( list_one, list_two, list_three) এবং তিনটি অ্যাঙ্কর এবং উপাধি রয়েছে যেখানে এই ম্যাপিংগুলিকে উল্লেখ করা হয় যেখানে উপযুক্ত।

প্রোগ্রামে ওয়াইএএমএল ফাইলটি লোড হওয়ার পরে আমরা যে তালিকাটি চাই তা পাই তবে এটি লোডের পরে কিছুটা সংশোধন করার প্রয়োজন হতে পারে (নীচের ক্ষতিগুলি দেখুন)।

উদাহরণ

আসল ওয়াইএএমএল ফাইল

  list_one: & id001
   - ক
   - খ
   - গ

  list_two: & id002
   - ই
   - চ
   - ছ

  list_three: & id003
   - এইচ
   - i
   - জে

  তালিকা_ সংযুক্ত:
      - * আইডি 1001
      - * ID002
      - * ID003

YAML.safe_load এর পরে ফলাফল

## তালিকা_ সংযুক্ত
  [
    [
      "এ",
      "খ",
      "সি"
    ],
    [
      "ই",
      "f",
      "ছ"
    ],
    [
      "এইচ",
      "আমি",
      "জ"
    ]
  ]

বিপদ

উপসংহার

এই পদ্ধতিটি ওয়াইএএমএল এর নাম এবং অ্যাঙ্কর বৈশিষ্ট্যটি ব্যবহার করে মার্জড তালিকাগুলি তৈরির অনুমতি দেয়।

যদিও আউটপুট ফলাফল তালিকার একটি নেস্টেড তালিকা, তবে flattenপদ্ধতিটি ব্যবহার করে এটি সহজেই রূপান্তরিত হতে পারে ।

আরো দেখুন

@ অ্যানথনের বিকল্প বিকল্পটি আপডেট হয়েছে

flattenপদ্ধতির উদাহরণ


23

এটি কাজ করে না:

  1. মার্জ শুধুমাত্র ম্যাপিংয়ের জন্য ওয়াইএএমএল স্পেসিফিকেশন দ্বারা সমর্থিত এবং ক্রমগুলির জন্য নয় merge

  2. আপনি << কী / মান বিভাজক :এবং একটি মান যা একটি রেফারেন্স এবং তারপরে একই ইন্ডেন্টেশন পর্যায়ে একটি তালিকা দিয়ে চালিয়ে যাওয়ার পরে একটি মার্জ কী থাকার মাধ্যমে আপনি জিনিসগুলি সম্পূর্ণরূপে মিশ্রিত করছেন

এটি YAML সঠিক নয়:

combine_stuff:
  x: 1
  - a
  - b

সুতরাং আপনার উদাহরণ বাক্য গঠনটি ওয়াইএএমএল এক্সটেনশন প্রস্তাব হিসাবেও বোঝায় না।

আপনি যদি একাধিক অ্যারে মার্জ করার মতো কিছু করতে চান তবে আপনি একটি বাক্য গঠন যেমন বিবেচনা করতে পারেন:

combined_stuff:
  - <<: *s1, *s2
  - <<: *s3
  - d
  - e
  - f

যেখানে s1, s2, s3সিকোয়েন্স (দেখানো হয়নি) যে আপনি একটি নতুন ক্রম মধ্যে একত্রীকরণ করতে চান এবং তারপর উপর নোঙ্গর হয় d, eএবং f যে যোগ করা। তবে ওয়াইএএমএল প্রথমে এই ধরণের কাঠামোর গভীরতার সমাধান করছে, সুতরাং মার্জ কীটি প্রক্রিয়াকরণের সময় কোনও বাস্তব প্রসঙ্গ পাওয়া যায় না। আপনার কাছে এমন কোনও অ্যারে / তালিকা উপলব্ধ নেই যেখানে আপনি প্রক্রিয়াজাত মানটি (অ্যাঙ্কার্ড সিকোয়েন্স) সংযুক্ত করতে পারেন।

আপনি @ ড্রেফটিম্যাকের প্রস্তাবিত মতামতটি নিতে পারেন, তবে এটির বিশাল অসুবিধা রয়েছে যা আপনার কোনওভাবে জানা উচিত যে কোন নেস্টেড ক্রমগুলি ফ্ল্যাট করতে হবে (অর্থাত বোঝা ডেটা কাঠামোর মূল থেকে প্যারেন্ট সিকোয়েন্স পর্যন্ত "পথ" জেনে), বা আপনি যে পুনরাবৃত্তভাবে নেস্টেড অ্যারে / তালিকাগুলি অনুসন্ধান করে ভারী ডেটা স্ট্রাকচারটি হাঁটেন এবং নির্বিচারে তাদের সকলকে সমতল করুন।

আইএমও এর চেয়ে আরও ভাল সমাধান হ'ল ডেটা স্ট্রাকচার লোড করতে ট্যাগ ব্যবহার করা যা আপনার জন্য চাটুকার্য করে। এটি কী সমতল করতে হবে এবং কোনটি নয় এবং কীভাবে এই ফ্ল্যাটিং লোডিংয়ের সময় করা হয়, বা অ্যাক্সেসের সময় করা হয়েছিল তা পুরো নিয়ন্ত্রণ দেয় তা স্পষ্টভাবে বোঝানোর অনুমতি দেয়। কোনটি চয়ন করা তা সময় এবং স্টোরেজ স্পেসে প্রয়োগকরণ এবং দক্ষতার স্বাচ্ছন্দ্যের বিষয়। এটি একই বাণিজ্য বন্ধ যা মার্জ কী বৈশিষ্ট্যটি বাস্তবায়নের জন্য করা দরকার এবং এর কোনও একক সমাধান নেই যা সর্বদা সেরা।

উদাহরণস্বরূপ, আমার ruamel.yamlলাইব্রেরিটি নিরাপদ-লোডার ব্যবহারের সময় লোডের সময় ব্রুট ফোর্স মার্জ-ডিক্টস ব্যবহার করে, যার ফলে মার্জড ডিকশনারিগুলি পাওয়া যায় যা পাইথন ডিক্টস are এই মার্জিংটি আপ-ফ্রন্ট করতে হবে এবং ডুপ্লিকেটস ডেটা (স্পেস অদক্ষ) তবে মান সন্ধানে দ্রুত। রাউন্ড-ট্রিপ-লোডার ব্যবহার করার সময়, আপনি মার্জগুলি নিমজ্জিত করে ফেলতে সক্ষম করতে চান, তাই তাদের আলাদা রাখা দরকার। রাউন্ড-ট্রিপ-লোডিংয়ের ফলে লোড হওয়া ডেটাস্ট্রাক্টের মতো ডিকটি স্থান দক্ষ কিন্তু অ্যাক্সেসের চেয়ে ধীর, কারণ এটি ডিলের মধ্যে মার্জগুলিতে পাওয়া যায় না এমন কীটি অনুসন্ধান করার চেষ্টা করতে হবে (এবং এটি ক্যাশেড নয়, তাই এটি প্রতিবার করা দরকার)। অপেক্ষাকৃত ছোট কনফিগারেশন ফাইলগুলির জন্য এই জাতীয় বিবেচনাগুলি খুব গুরুত্বপূর্ণ নয়।


নিম্নলিখিতটি পাইথন সহ অবজেক্টগুলিতে তালিকার জন্য সংযুক্তির মতো প্রকল্পের জন্য একীকরণের মতো প্রকল্প প্রয়োগ করে flatten যা অন-দ্য ফ্লাইটি তালিকা এবং ট্যাগযুক্ত আইটেমগুলিতে পুনরাবৃত্তি করে toflatten। এই দুটি ট্যাগ ব্যবহার করে আপনার ওয়াইএএমএল ফাইল থাকতে পারে:

l1: &x1 !toflatten
  - 1 
  - 2
l2: &x2
  - 3 
  - 4
m1: !flatten
  - *x1
  - *x2
  - [5, 6]
  - !toflatten [7, 8]

(ফ্লো বনাম ব্লক স্টাইল সিকোয়েন্সগুলির ব্যবহার সম্পূর্ণ স্বেচ্ছাসেবী এবং লোড হওয়া ফলাফলের কোনও প্রভাব রাখে না)।

আইটেমগুলির m1মধ্যে পুনরুক্তি করার সময় কীটির মান হ'ল এই "পুনরাবৃত্তি" এর সাথে ট্যাগ করা অনুক্রমগুলিতে toflatten, তবে অন্যান্য তালিকাগুলি (উপজাত বা না) একক আইটেম হিসাবে প্রদর্শন করে lays

পাইথন কোডটি অর্জনের একটি সম্ভাব্য উপায় হ'ল:

import sys
from pathlib import Path
import ruamel.yaml

yaml = ruamel.yaml.YAML()


@yaml.register_class
class Flatten(list):
   yaml_tag = u'!flatten'
   def __init__(self, *args):
      self.items = args

   @classmethod
   def from_yaml(cls, constructor, node):
       x = cls(*constructor.construct_sequence(node, deep=True))
       return x

   def __iter__(self):
       for item in self.items:
           if isinstance(item, ToFlatten):
               for nested_item in item:
                   yield nested_item
           else:
               yield item


@yaml.register_class
class ToFlatten(list):
   yaml_tag = u'!toflatten'

   @classmethod
   def from_yaml(cls, constructor, node):
       x = cls(constructor.construct_sequence(node, deep=True))
       return x



data = yaml.load(Path('input.yaml'))
for item in data['m1']:
    print(item)

কোন ফলাফল:

1
2
[3, 4]
[5, 6]
7
8

আপনি দেখতে পাচ্ছেন যে, ক্রমানুসারে যা সমতলকরণ প্রয়োজন, আপনি একটি ট্যাগ্স সিকোয়েন্সে একটি উপনাম ব্যবহার করতে পারেন বা আপনি ট্যাগযুক্ত ক্রম ব্যবহার করতে পারেন। YAML আপনাকে করতে দেয় না:

- !flatten *x2

, অর্থাত্ একটি নোঙ্গরযুক্ত ক্রম ট্যাগ করুন, কারণ এটি এটিকে মূলত একটি আলাদা ডেটাস্ট্রাক্টারে পরিণত করে।

ব্যবহার স্পষ্ট ট্যাগ আইএমও কিছু জাদু YAML একত্রীকরণ কী এর মাধ্যমে যেমন চলছে থাকার চেয়ে ভাল <<। যদি আপনার আর কোনও কিছুই না হয় তবে আপনি যদি ম্যাপিংয়ের সাথে একটি ওয়াইএএমএল ফাইল <<রাখেন যা একটি কী রয়েছে যা আপনি কোনও মার্জ কী এর মতো কাজ করতে চান না, যেমন আপনি যখন সি অপারেটরদের বিবরণে ম্যাপিং করেন তখন ইংরাজীতে (বা অন্য কোনও প্রাকৃতিক ভাষায়)।


11

আপনার যদি কেবলমাত্র একটি আইটেমকে তালিকার মধ্যে মার্জ করতে হয় তবে আপনি করতে পারেন

fruit:
  - &banana
    name: banana
    colour: yellow

food:
  - *banana
  - name: carrot
    colour: orange

যা ফলন দেয়

fruit:
  - name: banana
    colour: yellow

food:
  - name: banana
    colour: yellow
  - name: carrot
    colour: orange

-5

আপনি এই শর্তগুলির অধীনে ম্যাপিংগুলিকে মার্জ করে তার কীগুলি একটি তালিকায় রূপান্তর করতে পারেন:

  • আপনি যদি jinja2 টেম্প্লেটিং ব্যবহার করছেন এবং
  • আইটেম অর্ডার গুরুত্বপূর্ণ না হলে
some_stuff: &some_stuff
 a:
 b:
 c:

combined_stuff:
  <<: *some_stuff
  d:
  e:
  f:

{{ combined_stuff | list }}

এই উত্তরটিতে কি দোষ? ডাউনভোটদের যদি তর্ক করা হয় তাতে আমার আপত্তি নেই। আমি যারা এটি ব্যবহার করতে পারি তাদের জন্য উত্তরটি রাখব।
sm4rk0

4
সম্ভবত কারণ এই উত্তরটি জিনজা 2 টেম্প্লেটিংয়ের উপর নির্ভর করে, যখন প্রশ্নটি এটি ইউএমএলে করতে বলে। জিনজা 2 এর একটি পাইথন পরিবেশ প্রয়োজন, যা ওপি ড্রাই করার চেষ্টা করলে প্রতি-উত্পাদনশীল counter এছাড়াও, অনেক সিআই / সিডি সরঞ্জাম কোনও টেম্প্লেটিং পদক্ষেপ গ্রহণ করে না।
জর্জি লিটাও

ধন্যবাদ @ জোর্জেলিটাও। এটা বোধগম্য. উত্তর প্লেবুক এবং টেমপ্লেটগুলি বিকাশ করার সময় আমি YAML এবং Jinja2 একসাথে শিখেছি এবং অন্যটি ছাড়া একটি সম্পর্কে ভাবতে পারি না
sm4rk0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.