bash - 変数int値を使用して関数の位置パラメータを参照する

bash - 変数int値を使用して関数の位置パラメータを参照する

変数を使いたいです。

i=1

スクリプトへの参照として渡された位置変数の値。例:

x=101
y=201
z=301

foo(){
    echo "$1"
    echo "$2"
    echo "$3"
}

foo x y z

出力:

101
201
301

iインデックスごとに各パラメータを参照するのではなく、インデックス変数を使用してインクリメントするにはどうすればよいですか?

言う:

foo() {
    local i=1
    echo "$i" #echo first paramter
    (( i+=1 ))
    echo "$i" #echo second parameter
    #etc.
}

この部分の構文は何ですかecho "$i"

@Ericの回答後に更新されました

~$ t=5
~$ foo() { i=1; echo "${!i}"; }
~$ foo t
t
~$

アップデート#2

簡単に言えば、私の方法を操作できる唯一の方法は次のとおりです。

foo() { #assuming 3 parameters

    i=0
    (( i+=1 ))
    var="${!i}"
    echo "${!var}"

    (( i+=1 ))
    var="${!i}"
    echo "${!var}"

    (( i+=1 ))
    var="${!i}"
    echo "${!var}"        
}

答え1

これはSO質問に似ていますここ、これは@costasコメントに似ています。以下を使用して$#パラメータ数を取得できます。間接参照${!i}名前で変数にアクセスするのと同じです。例は次のとおりです。

f() {
    for((i=1; i<=$#; i++)); do
        printf "%d %s\n" "$i" "${!i}"
    done
}

f a b c

印刷:

1 a
2 b
3 c

変数名を位置引数として渡す場合は、次のように間接参照レイヤーを追加できます。

a=first
b=second
c=third

f() {
    for((i=1; i<=$#; i++)); do
        var="${!i}"
        printf "%d %s\n" "$i" "${!var}"
    done
}

f a b c

印刷

1 first
2 second
3 third

これにより、各パラメータを変数名として処理してそこに保存できますvar。それから私たちはprintf

一度に1レベルの間接参照のみを取得でき、入れ子には効果がありません。したがって、一度にやろうとすると、${!${!i}}最初から{拡張が開始され、残りは拡張される PARAMETER 値として扱われるので役に立ちません。最初の文字は、!残りの文字を必要なパラメータ名を含むPARAMETER名として扱いますが、${!i}有効なパラメータ名ではないため、bad substitution2つの手順でこの問題を回避できます。

答え2

を使用すると、shift次のことができます。

num_args="$#"

for (( i = 1; i <= "$num_args"; i++ )); do
    echo "$1"
    shift
done

ここでのshiftコマンドは変化スクリプトに渡される引数の各次の引数はの値です$1

たとえば、

$ ./myscript one two three four five six
one
two
three
four
five
six

ここでループの最初の実行では$1 = "one"、ループの 2 番目の実行では、$1 = "two"最後の引数まで続きます。


編集する:順序なしでスクリプトパラメータにアクセスしたい場合。 2番目と4番目の引数の両方を使用する1つの方法は、次のようにbash配列を使用することです。

# Initialize the array 'myargs' with all script arguments
myargs=( "$@" )

for (( i = 0; i < "$#"; i++ )); do
    echo "${myargs[$i]}"
done

iここでフォームを使用して、指定されたインデックスを持つすべてのパラメータにアクセスできます"${myargs[$i]}"

関連情報