YAMLのマージ
30分プログラム、その220。id:mzp:20080107:collectで作ったYAMLをマージするためのプログラム。
yaml-merge -key=some_key a.yaml b.yaml
とすると、a.yamlとb.yamlを併せて出力する。ただし、このときa.yamlとb.yamlに同じエントリが存在した場合は、b.yamlのエントリを優先する。
また、YAMLの内容は、
--- id: foo body: aaaaa... --- id: bar body: bbbbb...
のような連想リストっぽい内容を想定してる。直接ハッシュで書かないのは、YAMLが見づらい気がするので。
これはマージじゃなくてパッチと名付けたほうがよかった気がちょっとしてる。
使い方
$ cat base.yaml --- category: - Python title: cat -n url: http://d.hatena.ne.jp/mzp/20080101/cat $ cat delta.yaml --- category: - Python title: cat -n url: http://d.hatena.ne.jp/mzp/20080101/cat --- category: - Python title: SQLiteをPythonで url: http://d.hatena.ne.jp/mzp/20080102/sqlite $ yaml-merge --key=url base.yaml delta.yaml --- category: - Python title: cat -n url: http://d.hatena.ne.jp/mzp/20080101/cat --- category: - Python title: SQLiteをPythonで url: http://d.hatena.ne.jp/mzp/20080102/sqlite
ソースコード
#! /usr/bin/perl # -*- mode:perl; coding:utf-8 -*- # # yaml-merge.pl - # # Copyright(C) 2008 by mzp # Author: MIZUNO Hiroki / mzpppp at gmail dot com # http://howdyworld.org # # Timestamp: 2008/01/10 14:23:11 # # This program is free software; you can redistribute it and/or # modify it under MIT Lincence. # use strict; use warnings; use Getopt::Long; use Data::Dumper; use YAML qw(LoadFile Dump); # convert assoc array to hash sub to_hash($@){ my ($key,@assoc) = @_; my %hash; for (@assoc) { $hash{$_->{$key}} = $_; } %hash; } sub to_array(%){ my (%hash) = @_; map { $hash{$_}} sort keys %hash; } my $key; GetOptions('key|k=s'=>\$key); $key or die "usage: $0 --key=<key> <base-yaml> <delta-yaml>"; my ($base,$delta) = @ARGV; my @base = LoadFile $base; my @delta = LoadFile $delta; # if @base and @delta have same key, we select @delta entry. my %merged = ( to_hash($key,@base), to_hash($key,@delta) ); print Dump(to_array(%merged));