同じコマンドの各出力を異なる変数に保存する

同じコマンドの各出力を異なる変数に保存する
#!/bin/bash

SERVERLABEL=( 11011-22022 33033-44044-10101 55055-10001-20002 )

    for vmlabel in "${SERVERLABEL[@]}"
    do 
        linode-cli linodes list | grep $vmlabel | grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
    done

上記は私のスクリプトです。私が望むのは、各仮想マシンのipv4を別の環境変数に保存することです。

ipv4_11011-22022
ipv4_33033-44044-10101
ipv4_55055-10001-20002

私はbashスクリプトが初めてです。誰でも助けることができますか?

ベストアンサー1

使用連想配列:

#!/bin/bash

SERVERLABEL=( 11011-22022 33033-44044-10101 55055-10001-20002 )

declare -A ips # declare an associative array explicitly 

for vmlabel in "${SERVERLABEL[@]}"
do 
    ips[ipv4_$vmlabel]=$(
        linode-cli linodes list |
            grep -F -- "$vmlabel" |
            grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
    )
done

これを減らすことができますしない正規表現

linode-cli linodes list |
    grep -F -- "$vmlabel" |
    perl -MRegexp::Common -lne 'print for /$RE{net}{IPv4}/g'

より読みやすく、メンテナンスが簡単です。そうではありませんか?

または、自分で実行できるgrepタスクをスキップすることがあります。perl

linode-cli linodes list |
    perl -MRegexp::Common -lnse '
        if (/\Q$vmlabel\E/) {
            print for /$RE{net}{IPv4}/g
        }' -- -vmlabel="$vmlabel"

perlさらに一歩進んで、すべてのタスクを(またはその問題に適したプログラミング言語)で実行しますbash一つ電話linode-cliしてより安定的かつ効率的にしましょう。

取得したデータを表示

printf '%s\n' "${!ips[@]}"                     # keys
printf '%s\n' "${ips[@]}"                      # values
printf '%s\n' "${ips[ipv4_55055-10001-20002]}" # display only one key/value pair

greporはperl部分文字列と一致するため、$vmlabelaは、たとえば、次を含むすべての行grep -F -- 11011-22022と一致します。これを防ぐためにオプションを追加することもできます。11011-22022211011-220221-wgrep

おすすめ記事