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

関連情報