Yaml

如何從 YAML 文件中提取幾個 IP 地址

  • February 23, 2022

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}

一個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

sedcmd 執行以下操作:

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

使用perlYAML模組:

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

如果您的版本不支持,請使用%{$h{$_}}而不是。$h{$_}->%*``perl

與處理 JSON 的方式相同,在 shell 中使用適當的工具可以更好地處理:jq如果有類似的 YAML 工具怎麼辦?

實際上有一個jq名為 … 的包裝器yq,可以像jqYAML 輸入一樣使用。它似乎沒有打包在發行版中。無論如何,一旦建構並安裝了這個 python 命令(沿著jq廣泛可用的強制性工具),現在可以相應地解析 YAML 文件,因為它自然會忽略註釋。

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

只要語法有效,它將在主伺服器中轉儲 IP 地址。

引用自:https://unix.stackexchange.com/questions/691476