これは基本的な質問ですが、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
$name
cen2.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
コマンドラインで提供されているファイルを使用しないため、-n
withを使用してください。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