Programing

Linux 쉘 스크립트에서 YAML 파일을 구문 분석하려면 어떻게해야합니까?

crosscheck 2020. 5. 29. 07:59
반응형

Linux 쉘 스크립트에서 YAML 파일을 구문 분석하려면 어떻게해야합니까?


기술적으로 익숙하지 않은 사용자가 편집 할 수있는 구조화 된 구성 파일 (불행히도 파일이어야 함)을 제공하고 YAML을 사용하고 싶었습니다. 그러나 유닉스 쉘 스크립트에서 이것을 파싱하는 방법을 찾을 수 없습니다.


내 유스 케이스는이 원래 게시물이 요청한 것과 완전히 같거나 같지 않을 수도 있지만 확실히 유사합니다.

bash 변수로 일부 YAML을 가져와야합니다. YAML은 한 수준 이상이 될 수 없습니다.

YAML은 다음과 같습니다.

KEY:                value
ANOTHER_KEY:        another_value
OH_MY_SO_MANY_KEYS: yet_another_value
LAST_KEY:           last_value

dis와 같은 출력 :

KEY="value"
ANOTHER_KEY="another_value"
OH_MY_SO_MANY_KEYS="yet_another_value"
LAST_KEY="last_value"

이 줄로 출력을 얻었습니다.

sed -e 's/:[^:\/\/]/="/g;s/$/"/g;s/ *=/=/g' file.yaml > file.sh
  • s/:[^:\/\/]/="/g(URL의 경우) 를 무시하면서 찾은 다음 :로 대체합니다.="://
  • s/$/"/g"각 줄의 끝에 추가
  • s/ *=/=/g 전에 모든 공백을 제거합니다 =

다음은 sed와 awk를 사용하여 간단한 yaml 파일을 구문 분석하는 bash 전용 파서입니다.

function parse_yaml {
   local prefix=$2
   local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
   sed -ne "s|^\($s\):|\1|" \
        -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
        -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
   awk -F$fs '{
      indent = length($1)/2;
      vname[indent] = $2;
      for (i in vname) {if (i > indent) {delete vname[i]}}
      if (length($3) > 0) {
         vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
         printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
      }
   }'
}

다음과 같은 파일을 이해합니다.

## global definitions
global:
  debug: yes
  verbose: no
  debugging:
    detailed: no
    header: "debugging started"

## output
output:
   file: "yes"

다음을 사용하여 구문 분석 할 때

parse_yaml sample.yml

출력합니다 :

global_debug="yes"
global_verbose="no"
global_debugging_detailed="no"
global_debugging_header="debugging started"
output_file="yes"

또한 루비로 생성 된 yaml 파일을 이해하는데, 다음과 같이 루비 기호가 포함될 수 있습니다.

---
:global:
  :debug: 'yes'
  :verbose: 'no'
  :debugging:
    :detailed: 'no'
    :header: debugging started
  :output: 'yes'

이전 예제와 동일하게 출력됩니다.

스크립트 내에서 일반적인 용도는 다음과 같습니다.

eval $(parse_yaml sample.yml)

parse_yaml은 접두사 인수를 허용하므로 가져온 설정에는 공통 접두사가 있습니다 (네임 스페이스 충돌 위험을 줄입니다).

parse_yaml sample.yml "CONF_"

수율 :

CONF_global_debug="yes"
CONF_global_verbose="no"
CONF_global_debugging_detailed="no"
CONF_global_debugging_header="debugging started"
CONF_output_file="yes"

파일의 이전 설정은 다음 설정으로 참조 할 수 있습니다.

## global definitions
global:
  debug: yes
  verbose: no
  debugging:
    detailed: no
    header: "debugging started"

## output
output:
   debug: $global_debug

또 다른 좋은 사용법은 기본 파일을 먼저 구문 분석 한 다음 사용자 설정을 구문 분석하는 것입니다.이 설정은 첫 번째 설정보다 우선합니다.

eval $(parse_yaml defaults.yml)
eval $(parse_yaml project.yml)

shyaml쉘 명령 줄에서 YAML 쿼리 요구 사항을 파이썬으로 작성 했습니다.

개요 :

$ pip install shyaml      ## installation

예제의 YAML 파일 (복잡한 기능 포함) :

$ cat <<EOF > test.yaml
name: "MyName !!"
subvalue:
    how-much: 1.1
    things:
        - first
        - second
        - third
    other-things: [a, b, c]
    maintainer: "Valentin Lab"
    description: |
        Multiline description:
        Line 1
        Line 2
EOF

기본 검색어 :

$ cat test.yaml | shyaml get-value subvalue.maintainer
Valentin Lab

복잡한 값에 대한 더 복잡한 루핑 쿼리 :

$ cat test.yaml | shyaml values-0 | \
  while read -r -d $'\0' value; do
      echo "RECEIVED: '$value'"
  done
RECEIVED: '1.1'
RECEIVED: '- first
- second
- third'
RECEIVED: '2'
RECEIVED: 'Valentin Lab'
RECEIVED: 'Multiline description:
Line 1
Line 2'

몇 가지 핵심 사항 :

  • 모든 YAML 유형과 구문의 이상은 여러 줄, 따옴표 붙은 문자열, 인라인 시퀀스로 올바르게 처리됩니다.
  • \0 패딩 된 출력은 견고한 여러 줄 입력 조작에 사용할 수 있습니다.
  • 하위 값을 선택하는 간단한 점 표기법 (예 : subvalue.maintainer유효한 키)
  • 인덱스에 의한 액세스가 시퀀스에 제공됩니다 (즉 subvalue.things.-1, subvalue.things시퀀스 의 마지막 요소 입니다).
  • bash 루프에서 사용하기 위해 한 번에 모든 시퀀스 / 구조 요소에 액세스
  • YAML 파일의 전체 하위 부분을 YAML로 출력 할 수 있습니다. YAML은 shyaml을 사용한 추가 조작에 적합합니다.

shyaml github 페이지 또는 shyaml PyPI 페이지 에서 더 많은 샘플 및 문서를 사용할 수 있습니다 .


파이썬과 같은 일부 인터프리터에게 작은 스크립트를 전달할 수 있습니다. Ruby와 YAML 라이브러리를 사용하는 쉬운 방법은 다음과 같습니다.

$ RUBY_SCRIPT="data = YAML::load(STDIN.read); puts data['a']; puts data['b']"
$ echo -e '---\na: 1234\nb: 4321' | ruby -ryaml -e "$RUBY_SCRIPT"
1234
4321

여기서 datayaml의 값이있는 해시 (또는 배열)입니다.

보너스로 Jekyll의 앞면 문제 는 잘 해석 될 것 입니다.

ruby -ryaml -e "puts YAML::load(open(ARGV.first).read)['tags']" example.md

yq 는 경량의 휴대용 명령 줄 YAML 프로세서입니다.

프로젝트의 목적은 yaq 파일 jq 또는 sed 가되는 것 입니다.

( http://mikefarah.github.io/yq/ )

다음과 같은 sample.yaml 파일을 예로 들어 ( 문서 에서 직접 도난당한 )

---
bob:
  item1:
    cats: bananas
  item2:
    cats: apples

그때

yq r sample.yaml bob.*.cats

출력합니다

- bananas
- apples

Python3과 PyYAML은 현재 충족하기 쉬운 종속성이기 때문에 다음이 도움이 될 수 있습니다.

yaml() {
    python3 -c "import yaml;print(yaml.load(open('$1'))$2)"
}

VALUE=$(yaml ~/my_yaml_file.yaml "['a_key']")

파서가 YAML 문서에서 추출하려는 대상에 따라 다르므로 말하기 어렵습니다. 간단한 경우를 들어, 사용할 수 있습니다 grep, cut, awk사용할 필요가 더 복잡한 구문 분석 등 본격적인 파이썬으로 라이브러리 등을 분석 PyYAML 또는 YAML :: 펄 .


방금 내가 Yay 라고 부르는 파서를 작성했습니다 ! ( Yaml은 Yamlesque가 아닙니다! ) YAML의 작은 하위 집합 인 Yamlesque 를 구문 분석 합니다. 따라서 Bash를 100 % 준수하는 YAML 파서를 찾고 있다면 그렇지 않습니다. 그러나 OP를 인용하자면, 기술이 아닌 사용자 가 YAML과 같은 편집쉽게 할 수있는 구조화 된 구성 파일을 원한다면 이것은 관심이있을 것입니다.

그것은 이전 답변에 의해 퍼져 있지만 기본 변수 대신 연관 배열을 작성합니다 ( 예, Bash 4.x 필요 ). 데이터 기반 코드를 작성할 수 있도록 키에 대한 사전 지식없이 데이터를 구문 분석 할 수있는 방식으로 수행됩니다.

키 / 값 배열 요소뿐만 아니라 각 배열에는 keys키 이름 목록이 포함 된 children배열, 자식 배열의 이름이 포함 된 배열 및 parent부모를 참조 하는 키가 있습니다.

이것은 Yamlesque의 예입니다.

root_key1: this is value one
root_key2: "this is value two"

drink:
  state: liquid
  coffee:
    best_served: hot
    colour: brown
  orange_juice:
    best_served: cold
    colour: orange

food:
  state: solid
  apple_pie:
    best_served: warm

root_key_3: this is value three

다음 은 사용법을 보여주는 예입니다.

#!/bin/bash
# An example showing how to use Yay

. /usr/lib/yay

# helper to get array value at key
value() { eval echo \${$1[$2]}; }

# print a data collection
print_collection() {
  for k in $(value $1 keys)
  do
    echo "$2$k = $(value $1 $k)"
  done

  for c in $(value $1 children)
  do
    echo -e "$2$c\n$2{"
    print_collection $c "  $2"
    echo "$2}"
  done
}

yay example
print_collection example

어떤 출력 :

root_key1 = this is value one
root_key2 = this is value two
root_key_3 = this is value three
example_drink
{
  state = liquid
  example_coffee
  {
    best_served = hot
    colour = brown
  }
  example_orange_juice
  {
    best_served = cold
    colour = orange
  }
}
example_food
{
  state = solid
  example_apple_pie
  {
    best_served = warm
  }
}

파서는 다음 같습니다 .

yay_parse() {

   # find input file
   for f in "$1" "$1.yay" "$1.yml"
   do
     [[ -f "$f" ]] && input="$f" && break
   done
   [[ -z "$input" ]] && exit 1

   # use given dataset prefix or imply from file name
   [[ -n "$2" ]] && local prefix="$2" || {
     local prefix=$(basename "$input"); prefix=${prefix%.*}
   }

   echo "declare -g -A $prefix;"

   local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
   sed -n -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
          -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$input" |
   awk -F$fs '{
      indent       = length($1)/2;
      key          = $2;
      value        = $3;

      # No prefix or parent for the top level (indent zero)
      root_prefix  = "'$prefix'_";
      if (indent ==0 ) {
        prefix = "";          parent_key = "'$prefix'";
      } else {
        prefix = root_prefix; parent_key = keys[indent-1];
      }

      keys[indent] = key;

      # remove keys left behind if prior row was indented more than this row
      for (i in keys) {if (i > indent) {delete keys[i]}}

      if (length(value) > 0) {
         # value
         printf("%s%s[%s]=\"%s\";\n", prefix, parent_key , key, value);
         printf("%s%s[keys]+=\" %s\";\n", prefix, parent_key , key);
      } else {
         # collection
         printf("%s%s[children]+=\" %s%s\";\n", prefix, parent_key , root_prefix, key);
         printf("declare -g -A %s%s;\n", root_prefix, key);
         printf("%s%s[parent]=\"%s%s\";\n", root_prefix, key, prefix, parent_key);
      }
   }'
}

# helper to load yay data file
yay() { eval $(yay_parse "$@"); }

링크 된 소스 파일에 일부 문서가 있으며 아래는 코드의 기능에 대한 간단한 설명입니다.

yay_parse함수는 먼저 input파일을 찾거나 종료 상태 1로 종료합니다. 그런 다음 prefix명시 적으로 지정되거나 파일 이름에서 파생 된 데이터 세트를 판별합니다 .

유효한 bash명령을 표준 출력에 작성 하여 실행되는 경우 입력 데이터 파일의 내용을 나타내는 배열을 정의합니다. 이 중 첫 번째는 최상위 배열을 정의합니다.

echo "declare -g -A $prefix;"

배열 선언은 연관 ( -A)이며 Bash 버전 4의 기능입니다. 선언도 전역 ( -g)이므로 함수에서 실행될 수 있지만 yay도우미 와 같이 전역 범위에서 사용할 수 있습니다 .

yay() { eval $(yay_parse "$@"); }

입력 데이터는 처음에로 처리됩니다 sed. 유효한 Yamlesque 필드를 ASCII File Separator 문자로 구분 하고 값 필드 주위의 큰 따옴표를 제거 하기 전에 Yamlesque 형식 스펙과 일치하지 않는 행을 삭제 합니다.

 local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
 sed -n -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
        -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$input" |

두 표현은 비슷합니다. 첫 번째는 따옴표가없는 값을 선택하는 인용 된 값을 선택하기 때문에 다릅니다.

파일 분리기 비 인쇄 문자로, 입력 된 데이터에있을 가능성이 있기 때문 (28 / 12 진수 / 진수 034)이 사용된다.

결과는 awk한 번에 한 줄씩 입력을 처리하는 파이프로 연결됩니다 . FS 문자를 사용하여 각 필드를 변수에 지정합니다.

indent       = length($1)/2;
key          = $2;
value        = $3;

모든 줄에는 들여 쓰기 (0으로 표시)와 키가 있지만 모두 값이있는 것은 아닙니다. 선행 공백을 포함하는 첫 번째 필드의 길이를 2로 나누는 행의 들여 쓰기 레벨을 계산합니다. 들여 쓰기가없는 최상위 항목은 들여 쓰기 수준이 0입니다.

다음으로 prefix현재 항목에 사용할 항목을 알아 봅니다. 이것이 배열 이름을 만들기 위해 키 이름에 추가되는 것입니다. 있다 root_prefix데이터 세트 이름과 밑줄로 정의 최상위 배열 :

root_prefix  = "'$prefix'_";
if (indent ==0 ) {
  prefix = "";          parent_key = "'$prefix'";
} else {
  prefix = root_prefix; parent_key = keys[indent-1];
}

parent_key현재 라인의 덴트 레벨 위 오목 레벨의 키이며, 현재 라인의 일부 콜렉션을 나타낸다. 컬렉션의 키 / 값 쌍은 prefixand 의 연결로 정의 된 이름을 가진 배열에 저장됩니다 parent_key.

최상위 레벨 (인 덴트 레벨 0)의 경우 데이터 세트 접 두부가 상위 키로 사용되므로 접 두부가 없습니다 (로 설정 됨 ""). 다른 모든 배열 앞에는 접두사가 붙습니다.

다음으로 현재 키가 키를 포함하는 (awk-internal) 배열에 삽입됩니다. 이 배열은 전체 awk 세션 내내 유지되므로 이전 행에 의해 삽입 된 키를 포함합니다. 키는 들여 쓰기를 배열 인덱스로 사용하여 배열에 삽입됩니다.

keys[indent] = key;

이 배열에는 이전 줄의 키가 포함되어 있으므로 현재 줄의 들여 쓰기 수준보다 들여 쓰기 수준이 높은 모든 키가 제거됩니다.

 for (i in keys) {if (i > indent) {delete keys[i]}}

그러면 키 체인을 포함하는 키 배열이 루트에서 들여 쓰기 레벨 0의 루트에서 현재 행으로 남습니다. 이전 줄이 현재 줄보다 더 깊게 들여 쓰기되었을 때 남아있는 오래된 키를 제거합니다.

마지막 섹션은 bash명령을 출력 합니다. 값이없는 입력 줄은 새로운 들여 쓰기 수준 ( YAML 용어 모음)시작하고 값이있는 입력 줄은 현재 모음에 키를 추가합니다.

컬렉션 이름은 현재 줄 prefix의 연결입니다 parent_key.

키에 값이 있으면 해당 값을 가진 키가 다음과 같이 현재 컬렉션에 할당됩니다.

printf("%s%s[%s]=\"%s\";\n", prefix, parent_key , key, value);
printf("%s%s[keys]+=\" %s\";\n", prefix, parent_key , key);

첫 번째 명령문은 키의 이름을 지정한 연관 배열 요소에 값을 지정하는 명령을 출력하고 두 번째 명령문은 키를 콜렉션의 공백으로 구분 된 keys목록 에 추가하는 명령을 출력 합니다.

<current_collection>[<key>]="<value>";
<current_collection>[keys]+=" <key>";

키에 값이 없으면 다음과 같이 새 컬렉션이 시작됩니다.

printf("%s%s[children]+=\" %s%s\";\n", prefix, parent_key , root_prefix, key);
printf("declare -g -A %s%s;\n", root_prefix, key);

첫 번째 문은 현재 컬렉션의 공백으로 구분 된 children목록에 새 컬렉션을 추가하는 명령을 출력하고 두 번째 문은 새 컬렉션에 대한 새 연관 배열을 선언하는 명령을 출력합니다.

<current_collection>[children]+=" <new_collection>"
declare -g -A <new_collection>;

의 모든 출력 yay_parse은 bash eval또는 source내장 명령에 의해 bash 명령으로 구문 분석 될 수 있습니다 .


Stefan Farestam의 답변의 확장 버전은 다음과 같습니다.

function parse_yaml {
   local prefix=$2
   local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
   sed -ne "s|,$s\]$s\$|]|" \
        -e ":1;s|^\($s\)\($w\)$s:$s\[$s\(.*\)$s,$s\(.*\)$s\]|\1\2: [\3]\n\1  - \4|;t1" \
        -e "s|^\($s\)\($w\)$s:$s\[$s\(.*\)$s\]|\1\2:\n\1  - \3|;p" $1 | \
   sed -ne "s|,$s}$s\$|}|" \
        -e ":1;s|^\($s\)-$s{$s\(.*\)$s,$s\($w\)$s:$s\(.*\)$s}|\1- {\2}\n\1  \3: \4|;t1" \
        -e    "s|^\($s\)-$s{$s\(.*\)$s}|\1-\n\1  \2|;p" | \
   sed -ne "s|^\($s\):|\1|" \
        -e "s|^\($s\)-$s[\"']\(.*\)[\"']$s\$|\1$fs$fs\2|p" \
        -e "s|^\($s\)-$s\(.*\)$s\$|\1$fs$fs\2|p" \
        -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
        -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" | \
   awk -F$fs '{
      indent = length($1)/2;
      vname[indent] = $2;
      for (i in vname) {if (i > indent) {delete vname[i]; idx[i]=0}}
      if(length($2)== 0){  vname[indent]= ++idx[indent] };
      if (length($3) > 0) {
         vn=""; for (i=0; i<indent; i++) { vn=(vn)(vname[i])("_")}
         printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, vname[indent], $3);
      }
   }'
}

이 버전은 -사전 및 목록에 대한 표기법 및 짧은 표기법을 지원 합니다. 다음 입력 :

global:
  input:
    - "main.c"
    - "main.h"
  flags: [ "-O3", "-fpic" ]
  sample_input:
    -  { property1: value, property2: "value2" }
    -  { property1: "value3", property2: 'value 4' }

이 출력을 생성합니다.

global_input_1="main.c"
global_input_2="main.h"
global_flags_1="-O3"
global_flags_2="-fpic"
global_sample_input_1_property1="value"
global_sample_input_1_property2="value2"
global_sample_input_2_property1="value3"
global_sample_input_2_property2="value 4"

보시 -다시피 각 항목마다 다른 변수 이름을 얻기 위해 항목에 자동으로 번호가 매겨집니다. 에서 bash더 다차원 배열이없는, 그래서 이것은 해결하려면 한 가지 방법입니다. 여러 수준이 지원됩니다. @briceburg가 언급 한 후행 공백 문제를 해결하려면 작은 따옴표 또는 큰 따옴표로 값을 묶어야합니다. 그러나 여전히 몇 가지 제한 사항이 있습니다. 값과 쉼표가 포함 된 경우 사전 및 목록을 확장하면 잘못된 결과가 발생할 수 있습니다. 또한 ssh-key와 같은 여러 줄에 걸친 값과 같은 더 복잡한 구조는 (아직) 지원되지 않습니다.

코드에 대한 몇 마디 : 첫 번째 sed명령은 짧은 형식의 사전 { key: value, ...}을 일반으로 확장하고 더 간단한 yaml 스타일로 변환합니다. 두 번째 sed호출은 목록의 짧은 표기법에 대해서도 동일하게 적용되며 표기법이 [ entry, ... ]있는 항목 별 목록으로 변환 -됩니다. 세 번째 sed호출은 일반 사전을 처리 한 원래 호출이며 이제는 목록 -과 들여 쓰기 를 처리합니다 . awk부분은 각 들여 쓰기 수준에 대한 색인을 도입하고 변수 이름이 비어있을 때 (예 : 목록을 처리 할 때) 색인을 증가시킵니다. 빈 vname 대신 카운터의 현재 값이 사용됩니다. 한 레벨 위로 올라가면 카운터가 0이됩니다.

편집 : 이것을 위해 github 저장소만들었습니다 .


또 다른 옵션은 YAML을 JSON으로 변환 한 다음 jq를 사용하여 JSON 표현과 상호 작용하여 정보를 추출하거나 편집하는 것입니다.

이 접착제가 포함 된 간단한 bash 스크립트를 작성했습니다 -GitHub의 Y2J 프로젝트 참조


perl -ne 'chomp; printf qq/%s="%s"\n/, split(/\s*:\s*/,$_,2)' file.yml > file.sh

단일 값이 필요한 경우 jq예를 들어 YAML 문서를 JSON으로 변환하고 피드하는 도구를 사용할 수 yq있습니다.

sample.yaml의 내용 :

---
bob:
  item1:
    cats: bananas
  item2:
    cats: apples
  thing:
    cats: oranges

예:

$ yq -r '.bob["thing"]["cats"]' sample.yaml 
oranges

나는 이것이 매우 구체적이라는 것을 알고 있지만 내 대답은 특정 사용자에게 도움이 될 수 있다고 생각합니다.
당신이있는 경우 nodenpm사용자의 시스템에 설치, 당신은 사용할 수 있습니다 js-yaml.
첫 설치 :

npm i -g js-yaml
# or locally
npm i js-yaml

그런 다음 bash 스크립트에서

#!/bin/bash
js-yaml your-yaml-file.yml

또한 당신이 사용한다면 당신은 jq그런 것을 할 수 있습니다

#!/bin/bash
json="$(js-yaml your-yaml-file.yml)"
aproperty="$(jq '.apropery' <<< "$json")"
echo "$aproperty"

때문에 js-yaml변환 JSON 문자열 리터럴에 YAML 파일. 그런 다음 유닉스 시스템에서 json 파서와 함께 문자열을 사용할 수 있습니다.


당신이 파이썬 2 PyYAML이있는 경우, 당신은 내가라고 쓴이 파서 사용할 수 있습니다 parse_yaml.py을 . 깔끔한 기능 중 일부는 접두사를 선택하고 (유사한 변수를 가진 파일이 둘 이상인 경우) yaml 파일에서 단일 값을 선택하는 것입니다.

예를 들어 다음과 같은 yaml 파일이있는 경우 :

staging.yaml :

db:
    type: sqllite
    host: 127.0.0.1
    user: dev
    password: password123

prod.yaml :

db:
    type: postgres
    host: 10.0.50.100
    user: postgres
    password: password123

충돌없이 둘 다로드 할 수 있습니다.

$ eval $(python parse_yaml.py prod.yaml --prefix prod --cap)
$ eval $(python parse_yaml.py staging.yaml --prefix stg --cap)
$ echo $PROD_DB_HOST
10.0.50.100
$ echo $STG_DB_HOST
127.0.0.1

체리조차도 원하는 값을 고릅니다.

$ prod_user=$(python parse_yaml.py prod.yaml --get db_user)
$ prod_port=$(python parse_yaml.py prod.yaml --get db_port --default 5432)
$ echo prod_user
postgres
$ echo prod_port
5432

당신은 사용할 수 있습니다 상당YQ golang 기록한다 :

./go-yg -yamlFile /home/user/dev/ansible-firefox/defaults/main.yml -key
firefox_version

보고:

62.0.3

Grunt (JavaScript Task Runner) 사용을 고려할 수도 있습니다 . 쉘과 쉽게 통합 할 수 있습니다. YAML ( grunt.file.readYAML) 및 JSON ( grunt.file.readJSON) 파일 읽기를 지원 합니다.

이것은에서 작업을 생성함으로써 달성 될 수있다 Gruntfile.js(또는 Gruntfile.coffee), 예를 들면 :

module.exports = function (grunt) {

    grunt.registerTask('foo', ['load_yml']);

    grunt.registerTask('load_yml', function () {
        var data = grunt.file.readYAML('foo.yml');
        Object.keys(data).forEach(function (g) {
          // ... switch (g) { case 'my_key':
        });
    });

};

그런 다음 쉘에서 간단히 실행하십시오 grunt foo( grunt --help사용 가능한 작업 확인 ).

또한 출력을 원하는 형식으로 인쇄하기 위해 작업에서 전달 된 입력 변수로 exec:foo작업 ( grunt-exec)을 구현 foo: { cmd: 'echo bar <%= foo %>' }한 다음 다른 명령으로 파이프 할 수 있습니다.


Grunt와 비슷한 도구가 있으며, 추가 플러그인 gulp-yaml 과 함께 gulp 라고 합니다 .

다음을 통해 설치하십시오. npm install --save-dev gulp-yaml

샘플 사용법 :

var yaml = require('gulp-yaml');

gulp.src('./src/*.yml')
  .pipe(yaml())
  .pipe(gulp.dest('./dist/'))

gulp.src('./src/*.yml')
  .pipe(yaml({ space: 2 }))
  .pipe(gulp.dest('./dist/'))

gulp.src('./src/*.yml')
  .pipe(yaml({ safe: true }))
  .pipe(gulp.dest('./dist/'))

YAML 형식 을 처리하는 추가 옵션을 보려면 YAML 사이트 에서 사용 가능한 프로젝트, 라이브러리 및 해당 형식을 구문 분석하는 데 도움이되는 기타 리소스를 확인하십시오 .


다른 도구들 :

  • hon

    JSON 파싱, 읽기 및 생성

참고 URL : https://stackoverflow.com/questions/5014632/how-can-i-parse-a-yaml-file-from-a-linux-shell-script

반응형