2014-09-02 9 views
4

일부 스마트 파이핑 및 코딩을 사용하여 yaml 파일을 재귀 적으로 병합 할 수 있습니까? PHP에서, 나는 그것들의 배열을 만든다 (각 모듈은 /에서 시스템의 설정 노드를 추가하거나 업데이트 할 수있다).yaml 구성 파일을 bash로 재귀 적으로 병합

목표는 모든 개별 모듈 폴더의 구성 파일을 큰 병합 파일로 병합하는 내보내기 셸 스크립트입니다. FTP를 통해 새 버전을 배포하는 경우 모듈식이 필요하지 않으며 빠르고 효율적입니다.

그것은 PHP 함수처럼 행동한다 : array_merge_recursive

파일 시스템 구조는 다음과 같다 :

date: 
    format: 
     date_regular: %d-%m-%Y 

그리고, 말, 할 수있는 모듈 :

mod/a/config/sys.yml 
mod/a/config/another.yml 
mod/b/config/sys.yml 
mod/b/config/another.yml 
mod/c/config/totally-new.yml 
sys/config/sys.yml 

구성의 모습 이 :

date: 
    format: 
     date_regular: regular dates are boring 
     date_special: !!!%d-%m-%Y!!! 

지금까지 내가 가진 :

#!/bin/bash 
#........ 
cp -R $dir_project/ $dir_to/ 
for i in $dir_project/mod/*/ 
do 
    cp -R "${i}/." $dir_to/sys/ 
done 

물론 이것은 루프에서 기존의 모든 설정 파일 .. 기본적으로

(파일이 고유 한 이름있는 시스템의 나머지 부분), 나는에 대한 YAML 파서를 필요로 파괴 명령 줄 및 array_merge_recursive와 같은 옵션이 있습니다. 그런 다음 yaml 작가가 합쳐져 ​​병합되었습니다. 나는 bash가 이것을 자르지 않기 때문에 파이썬을 배워야 할까 봐 걱정한다.

답변

9

예를 들어 perl을 사용할 수 있습니다. 다음 oneliner : 다음 입력 파일에 대한

perl -MYAML::Merge::Simple=merge_files -MYAML -E 'say Dump merge_files(@ARGV)' f1.yaml f2.yaml 

:

date: 
    format: 
    date_regular: regular dates are boring 
    date_special: "!!!%d-%m-%Y!!!" 

가 병합 된 결과를 출력 f1.yaml

date: 
    epoch: 2342342343 
    format: 
    date_regular: "%d-%m-%Y" 

f2.yaml ...

--- 
date: 
    epoch: 2342342343 
    format: 
    date_regular: regular dates are boring 
    date_special: '!!!%d-%m-%Y!!!' 

때문에 @ 캐 일럽은 t 그는 지금 develeloper 모듈이며, 대체 모듈입니다.

perl -MYAML=LoadFile,Dump -MHash::Merge::Simple=merge -E 'say Dump(merge(map{LoadFile($_)}@ARGV))' f1.yaml f2.yaml 

는 상기와 동일 생산 Hash::Merge::Simple : 모듈이 약간 더 긴 두 개의 (하지만, 일반적으로 사용되는)을 사용한다.

+0

그리고 어떻게 의존성을 onliner에 설치하겠습니까? perl을 설치 한 리눅스 시스템에는 포함시킬 수 있지만이 특별한 의존성은 포함하지 마십시오. 예를 들어 데비안 시스템을 사용하십시오. perl에 오신 것을 환영합니다? – vaab

+0

다른 언어로 된 종속성 문제를 해결할 때와 똑같습니다. 라이브러리를 설치하십시오. 다음은 이미 CPAN 모듈을 설치하는 방법에 대한 몇 가지 질문입니다. 또는 OS 사전 포장 패키지를 사용하십시오. 나는 데비안에 대해 아무것도 모른다. 또는 이미 시스템에 설치되어있는 다른 라이브러리를 사용하십시오. (ay 언어로). – jm666

+0

이것은 CPAN의 모듈로도 사용할 수있는 것 같지 않으므로이를 설치하는 것에 대한 조언은 약간 분명한 것입니다. 내가 찾은 유일한 참고 자료는 [이 Github 저장소] (https://github.com/andrefs/YAML-Merge-Simple)입니다. – Caleb

0

는 배시에 메모리 임의 YAML 문서를 나타낼 수 없다 따라서 중첩 된 데이터 구조에 대한 지원 (그지도 현악기와를 정수로 인> 문자열이거나> 문자열 만)이 없으며.

이 작업에보다 강력한 언어를 사용하십시오.

+0

너무 나쁩니다. 루프를 사용하여 지역 변수를 가진 구조를 표현하려고하지 않는 것이 좋을 것입니다. 어떤 언어를 권장합니까, 파이썬? 저는 대부분의 플랫폼에서 사용할 수있는 다양한 언어를 배우는 것을 좋아합니다. – twicejr

+0

사실. 부수적으로 JSON과 XML을 bash가 쉽고 올바르게 작업 할 수있는 라인 지향 형식으로 변환하거나 변환 할 수있는 좋은 도구가 있지만 (1) 익숙한 YAML에는 아무 것도없고 (2) 실제 데이터 구조없이 병합 알고리즘을 실제로 구현하는 작업. –

+1

... 파이썬을 배우는 것은 가치가 있으며 재귀 트리 합치기 알고리즘을 구현하면 재발견하는 데 어려움이 있습니다. 나는 내가 기억할 수있는 것보다 더 많이했습니다. C에 익숙하다면 Go도 고려해보십시오. –

0

배쉬는 약간의 스트레칭 (이 작업을 수행 할 수는 있지만 오류가 발생하기 쉽습니다)입니다. 원하는 것이 있다면 에서 bash 쉘 (실제로 bash 함수를 사용하여 병합을 스크립팅하는 것과는 대조적으로)이라면 몇 가지 옵션이 있습니다.

나는 자바 기반의 yaml-merge 도구가 있음을 눈치 챘지만, 그 점이 내 생각에 어울리지 않아서 계속 찾고 있었다. 결국 yaml2jsonjq의 두 가지 도구를 사용하여 무언가를 하나로 묶었습니다. 경고

는 : JSON의 기능 YAML의의 only a subset 때문에,이 복잡한 YAML 구조의 무손실 과정이 아니다. 많은 간단한 키/값/시퀀스 시나리오에서 작동하지만 입력 YAML이 너무 화려하다면 문제를 일으킬 것입니다. 데이터 유형에 대해 테스트하여 예상대로 작동하는지 확인하십시오.

  1. 사용 yaml2json

    는 JSON에 입력을 변환 :

    yaml2json input1.yml > input1.json 
    yaml2json input2.yml > input2.json 
    
  2. 사용 jq는 객체를 반복하고 (자세한 내용은 this question and answers 참조) 재귀 적으로 병합 할 수 있습니다.

    jq -s 'reduce .[] as $item({}; . + $item)' input1.json input2.json > merged.json 
    
  3. 는 YAML에 다시 보자 :

    json2yaml merged.json > merged.yml 
    

는 물론 대본이, 원하는 경우 이전의 것들을 소지품 것입니다 나중에 사람의 값으로 중요성을 역순으로 목록 파일 일반적인 bash 메커니즘은 여러분의 친구입니다. 그리고 제가 여러분처럼 GNU-Make에있게된다면 다음과 같은 일이 트릭을 할 것입니다.

.SECONDEXPANSION: 
merged.yml: input1.yml input2.yml 
    json2yaml <(jq -s 'reduce .[] as $$item({}; . + $$item)' $(foreach YAML,$^,<(yaml2json $(YAML)))) > [email protected] 
관련 문제