YAML 파일에서 일부 IP 주소를 추출하는 방법

YAML 파일에서 일부 IP 주소를 추출하는 방법

이 파일이 있고 masters/hosts해당 섹션 아래의 모든 IP 주소를 선택하고 싶습니다(해당 행이 있는 경우).아니요댓글을 달았습니다. 나는 이것을 시도했지만 sed 's/.*\ \([0-9\.]\+\).*/\1/g'성공하지 못했습니다.

metal:
  children:
    masters:
      hosts:
        dev0: {ansible_host: 172.168.1.10}
        # dev1: {ansible_host: 185.168.1.11}
        # dev2: {ansible_host: 142.168.1.12}
    workers:
      hosts: {}
        # dev3: {ansible_host: 172.168.1.13}

답변1

JSON을 사용하는 것과 동일한 방식으로 셸에서 적절한 도구를 사용하는 것이 더 좋습니다.jq, YAML을 위한 유사한 도구가 있다면 어떨까요?

jq실제로 ...라는 래퍼가 있습니다 .yqjqYAML 입력처럼 사용할 수 있습니다 . 배포판에 포함되어 있지 않은 것 같습니다. 어쨌든, 이 Python 명령을 빌드하고 설치하면( jq널리 사용 가능한 강제 도구와 함께) 이제 그에 따라 YAML 파일을 구문 분석할 수 있습니다. 그러면 자연스럽게 주석이 무시됩니다.

yq -r '.metal.children.masters.hosts[].ansible_host' < myfile.yaml

구문이 유효한 한 마스터에서 IP 주소를 덤프합니다.

답변2

일방 sed통행:

sed -n '/masters:/n;/hosts:/{:a n;/^ *#* *dev[0-9]/!d;s/^ *dev[0-9]: {ansible_host: //;tl;ba;:l s/}//p;ba}' test

여러 줄 방식으로:

    sed -n '
         /masters:/n
         /hosts:/{
             :a n
             /^ *#* *dev[0-9]/!d
             s/^ *dev[0-9]: {ansible_host: //
             tl
             ba
             :l 
                  s/}//p
                  ba
         }' test

cmd는 sed다음을 수행합니다.

sed : /bin/sed the executable
-n : sed option to avoid auto printing
/masters:/n : If the current line is "master:" read the **n**ext line in the pattern space
/hosts:/{ : If the current line, the one read before, is "hosts:" do the following command block
:a n : Create a label called "a" and read the next line in the patter space.
/^ *#* *dev[0-9]/!d : If the current line, is **not** a dev[0-9] keyword (even commented) then delete current line and start a new cicle (exit from the loop)
s/^ *dev[0-9]: {ansible_host: // : sobstitute anything in the line except the ip address.
tl : If the preceding sobstitution succeded, then jump to the "l" label (skipping the next instruction).
ba : Is a commented line: Jump to the "a" label and read the next line.
:l : Create a new label called "l"
s/}//p : Remove the last "}" and print the pattern space (The ip address)
ba : Jump to label "a" to process the next line.
} : Close the code block opened by the match on the "host" line.


또는 awk:

awk '
    /masters:/{
        f=1
        next
    }
    /hosts:/ && f {
        f++
        next
    }
    /^ *dev[0-9]: [{]ansible_host: / && f == 2 {
         sub(/[}]$/, "", $NF)
         print $NF
         next
    }
    !/^ *#? ?dev[0-9]*:/ && f==2{f=0}
' test

perl모듈 포함 YAML:

perl -MYAML -le '
    $y = YAML::LoadFile "test";
    %h = %{$y->{metal}->{children}->{masters}->{hosts}};
     print values $h{$_}->%* for (keys %h)
'

귀하의 버전이 이를 지원하지 않는 경우 %{$h{$_}}대신 사용하십시오.$h{$_}->%*perl

관련 정보