ループ内で複数のBash配列を繰り返す際に発生する問題

ループ内で複数のBash配列を繰り返す際に発生する問題

Bashの配列にはいくつかの問題があります。

A=( "127.0.0.1" "localhost" "aaa nnn cvcc" )
B=( "8.8.8.8"  "dns" "bbb tttt rrrr")

for n in ${A} ${B} ;  do

 if ping -c3 ${n[0]};then
  echo "${n[1]}"
    for share in ${n[2]};do
      echo $share
    done
 fi
done

配列の2番目と3番目の要素を印刷したいのですが、forループはpingで停止します。だから動作します。

if ping -c3 ${A[0]};then
 echo "${A[1]}"
 for share in ${A[2]};do
  echo $share
 done
fi

本当に愚かなことですが、本当に狂っていると思います...アイデアがありますか?事前にありがとう

ベストアンサー1

Aループは実際にはandの最初の要素であるandを繰り返しますB。これは${A[0]}、andがwhileと同じ空の文字列であることを${B[0]}意味します。${n[1]}${n[2]}${n[0]}$n

bashバージョン4.3以降では、名前参照変数を使用してこれを実行できます。

#!/bin/bash

A=( 127.0.0.1 localhost alpha beta gamma theta )
B=( 8.8.8.8   dns       itsy bitsy 'spider man' )

for variable in A B; do
        declare -n array="$variable"

        if ping -c3 "${array[0]}" >/dev/null; then
                printf '%s\n' "${array[1]}"
                printf '\t%s\n' "${array[@]:2}"
        fi
done

変数を繰り返しています。名前 AそしてB、その内容よりは。ループ内でarrayという変数の名前参照を作成します$variable。 Nowはorarrayでのみ使用されます。AB

このif説明では、ループの3番目の配列要素を分割するためにシェルを使用しません。代わりに、A配列を作成するときにB手動で分割し、配列printfのオフセットを使用して単一の呼び出しを実行して要素を出力しますarray。読みやすくするために、各要素の前にタブを出力しました。

localhost
        alpha
        beta
        gamma
        theta
dns
        itsy
        bitsy
        spider man

このifステートメントは次のように書くこともできます。

if ping -c3 "${array[0]}" >/dev/null; then
        printf '%s: ' "${array[1]}"
        ( IFS=,; printf '%s\n' "${array[*]:2}" )
fi

残りの配列要素をコロンの後にカンマ区切りのリストとして出力します。

localhost: alpha,beta,gamma,theta
dns: itsy,bitsy,spider man

注:上記の引用は偶然ではありません。参照配列を拡張すると、各要素が個別に参照されます。個々の要素を引用する拡張は、シェルが空白に値を分割しないことを保証します(そして分割された単語に対してファイル名のグロービングを実行しません)。

また、見ることができます


/bin/sh名前付き配列を使用せずにこれを実行することもできます。代わりに、位置引数リストを使用してデータを保持し、リストの各部分を特別な単語(END選択したランダムな文字列であるを使用)で終了します。次にリストを繰り返し、リストから要素を削除します。

#!/bin/sh

set --  127.0.0.1 localhost alpha beta gamma theta END \
        8.8.8.8   dns       itsy bitsy 'spider man' END

while [ "$#" -gt 0 ]; do
        if ping -c 3 "$1" >/dev/null; then
                printf '%s\n' "$2"
                shift 2
                while [ "$1" != END ]; do
                        printf '\t%s\n' "$1"
                        shift
                done
        else
                while [ "$1" != END ]; do shift; done
        fi

        shift
done

おすすめ記事