Você pode usar join
para mesclar os dois arquivos e preservar a ordem das chaves. Aqui está um exemplo:
conf1
:
name='john'
last=''
custom='1000'
rule='default'
conf2
:
name='joe'
second='none'
fourth='dash'
last='star'
rule='whatever'
se você executar:
{ { join -t= -1 2 -2 1 -o 1.1 1.2 2.2 <(sort -t= -k2,2 <(nl -ba -nrz -s= conf1)) \
<(sort -t= -k1,1 conf2); join -t= -1 2 -2 1 -v1 -o 1.1 1.2 1.3 \
<(sort -t= -k2,2 <(nl -ba -nrz -s= conf1)) <(sort -t= -k1,1 conf2); \
} | sort -k1,1n | cut -d= -f2-; join -t= -1 1 -2 2 -v2 -o 2.1 2.2 2.3 \
<(sort -t= -k1,1 conf1) <(sort -t= -k2,2 <(nl -ba -nrz -s= conf2)) \
| sort -k1,1n | cut -d= -f2-; } > merged_conf
o conteúdo de merged_conf
é:
name='joe'
last='star'
custom='1000'
rule='whatever'
second='none'
fourth='dash'
Talvez seja mais fácil entender se estiver trabalhando com dois arquivos temporários. Primeiro n
umber as l
ines em conf1
e conf2
e sort
delas por 2
nd campo:
sort -t= -k2,2 <(nl -ba -nrz -s= conf1) >conf1.sorted
sort -t= -k2,2 <(nl -ba -nrz -s= conf2) >conf2.sorted
acima, cria conf1.sorted
:
000003=custom='1000'
000002=last=''
000001=name='john'
000004=rule='default'
e conf2.sorted
:
000003=fourth='dash'
000004=last='star'
000001=name='joe'
000005=rule='whatever'
000002=second='none'
Agora, o mesmo comando usando os arquivos originais e os arquivos numerados / classificados:
{ { join -t= -1 2 -2 1 -o 1.1 1.2 2.2 conf1.sorted <(sort -t= -k1,1 conf2); \
join -t= -1 2 -2 1 -v1 -o 1.1 1.2 1.3 conf1.sorted \
<(sort -t= -k1,1 conf2); } | sort -k1,1n | cut -d= -f2-; \
join -t= -1 1 -2 2 -v2 -o 2.1 2.2 2.3 <(sort -t= -k1,1 conf1) conf2.sorted \
| sort -k1,1n | cut -d= -f2-; } > merged_conf
Explicação:
join -t= -1 2 -2 1 -o 1.1 1.2 2.2 conf1.sorted <(sort -t= -k1,1 conf2)
une os arquivos com base no campo 2
de conf1.sorted
e campo 1
de conf2
imprimindo as linhas comuns, mas com os valores ( 2.2
) de conf2
:
000002=last='star'
000001=name='joe'
000004=rule='whatever
e
join -t= -1 2 -2 1 -v1 -o 1.1 1.2 1.3 conf1.sorted <(sort -t= -k1,1 conf2)
imprime as linhas não parciais de conf1.sorted
:
000003=custom='1000'
eles são agrupados em {..}
e a saída é canalizada para sort -k1,1n | cut -d= -f2-
para restaurar a ordem das chaves do original conf1
:
name='joe'
last='star'
custom='1000'
rule='whatever'
então
join -t= -1 1 -2 2 -v2 -o 2.1 2.2 2.3 <(sort -t= -k1,1 conf1) conf2.sorted
junta-se com base no campo 1
de conf1
e campo 2
de conf2.sorted
imprimindo linhas não parciais do último:
000003=fourth='dash'
000002=second='none'
da mesma maneira, a saída é canalizada para sort -k1,1n | cut -d= -f2-
para restaurar a ordem das chaves do original conf2
:
second='none'
fourth='dash'
Agrupar todos os itens acima produz a saída desejada:
name='joe'
last='star'
custom='1000'
rule='whatever'
second='none'
fourth='dash'
isso é redirecionado ( >
) para merged_conf
. Por fim, remova os arquivos classificados:
rm conf{1,2}.sorted
Isso pode ser repetido para arquivos de configuração adicionais usando merged_conf
e, por exemplo, conf3
como argumentos e assim por diante ...