如何从 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 的方式相同,在 shell 中使用适当的工具可以更好地处理:jq,如果 YAML 有类似的工具怎么办?

实际上有一个jq包装器叫做...yq可以像jqYAML 输入一样使用。它似乎没有打包在发行版中。无论如何,一旦构建并安装了这个 python 命令(以及jq广泛可用的强制工具),现在就可以相应地解析 YAML 文件,因为它自然会忽略注释。

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

只要语法有效,它将转储 master 中的 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

cmdsed执行以下操作:

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

相关内容