Mike Farahのyqを使用してyamlファイルにコンテンツを追加する

Mike Farahのyqを使用してyamlファイルにコンテンツを追加する

これは基本的な質問ですが、bashの経験がないため、これを行うのが困難です。

私に Directory_1 ディレクトリがあり、このディレクトリに cen1.yaml と cen2.yaml があるとします。 cen1.yamlにはnameというフィールドがあります。

name:xxxx

cen2.yamlの内容は異なる場合があります(例)。

service:ser1
image:
  field1:field1
  field2:field2
.
.
.

最初の反復には空のFinal.yamlがあります。しかし、私はこのファイルがcen1.yamlの名前を持ち、cen2のすべてのエントリがそのような名前を持つことを望みます。

xxxx:
  service:ser1
  image:
    field1:field1
    field2:field2
  .
  .
  .

次に、同じファイル名(cen1.yamlとcen2.yaml)を持つ別のディレクトリを複製します。 Cen1.yamlには再び名前フィールドがあります。

name:another

そしてcen2.yamlには独自のコンテンツがあります。

tv:lcd
name:
  field1:field1
  field2:field2
.
.
.

これで、既存のファイルに追加して同じ構造を維持する必要があります。

xxxx:
  service:ser1
  image:
    field1:field1
    field2:field2
  .
  .
  .
another
  tv:lcd
  mount:
    field1:field1
    field2:field2
  .
  .
  .

したがって、2つのケースで動作するコマンドが必要です。ファイルが空で最初の反復を作成する場合、またはファイルにすでに内容があり、内容が追加されている場合。この目標をどのように達成できますか?

答え1

yq以下は、名前をロードして内部変数cen1.yamlに入れるMike Farahの表現です。次に、下記のキーを使用して新しいYAML文書を作成し、その文書に読み込みます。yq$namecen2.yaml$name

load("cen1.yaml").name as $name | .[$name] = load("cen2.yaml")

これを使用して複数のサブディレクトリを繰り返し、yq各サブディレクトリに適用し、そこから出力を収集できますfinal.yaml。このコードは、ディレクトリがすべてファイル名のワイルドカードパターンと一致すると仮定しますdirectory_*

for dir in directory_*; do
(
    cd "$dir" &&
    yq -n 'load("cen1.yaml").name as $name | .[$name] = load("cen2.yaml")'
)
done >final.yaml

コマンドラインで提供されているファイルを使用しないため、-nwithを使用してください。yq

質問のデータを考慮すると(破線を削除し、それぞれの後にスペースを挿入することによって修正されます:)、次のYAMLファイルが生成されます。

xxxx:
  service: ser1
  image:
    field1: field1
    field2: field2
another:
  tv: lcd
  name:
    field1: field1
    field2: field2

すべてのディレクトリが同時に利用できない場合は、final.yamlビットを追加してファイルを構築できます。

rm -f final.yaml

# Get directory_1, and then...
(
    cd directory_1 &&
    yq -n 'load("cen1.yaml").name as $name | .[$name] = load("cen2.yaml")'
) >>final.yaml

# Get directory_2, and then...
(
    cd directory_2 &&
    yq -n 'load("cen1.yaml").name as $name | .[$name] = load("cen2.yaml")'
) >>final.yaml

# etc.

...デフォルトでは、ループの各反復を手動で実行し、各ステップの結果ファイルに出力を追加します。


同じことですが、Andrey Kislyukのyq(ラッパーjq)を使用してください。

for dir in directory_*; do
(
    cd "$dir" &&
    yq -n -y 'input.name as $name | .[$name] = inputs' cen1.yaml cen2.yaml
)
done >final.yaml

関連情報