forループでパラメータ値を使用する方法

forループでパラメータ値を使用する方法

スクリプトを実行しています。script.sh 12345 12346 12347

for z in 1..$(seq 1 $#);
do
    echo "param $z is $($(echo $z))"; //Line 4
done;

出力は次のようになると予想されます。

param 1 is 12345
param 2 is 12346
param 3 is 12347

4行目で何か抜けたようです。

答え1

問題は、$($(echo $z))まず$(1)(if $z1)に展開し、シェルが1それをコマンドとして実行しようとしていることです。


仮定bash:

params=( "$@" )

for (( i = 0; i < ${#params[@]}; ++i )); do
    printf 'Param %d is "%s"\n' "$i" "${params[i]}"
done

実行してください:

$ bash script.sh a b c
Param 0 is "a"
Param 1 is "b"
Param 2 is "c"

または以下を使用して/bin/sh

i=0
while [ "$#" -gt 0 ]; do
    printf 'Param %d is "%s"\n' "$i" "$1"
    i=$(( i + 1 ))
    shift
done

走る:

$ /bin/sh script.sh a b c
Param 0 is "a"
Param 1 is "b"
Param 2 is "c"

明示的に列挙する必要がある場合がそうです。一般的に我々は繰り返します"$@"

for param in "$@"; do
    printf 'Param: "%s"\n' "$param"
    # do other thing with "$param" here
done

答え2

for z in 1..$(seq 1 $#);

3 つのパラメータの場合、これは、1..12で拡張されます。すでに数字を別の単語で印刷しており、実際に数字のリストを作成することはできません。中かっこ拡張は数値リストを生成できますが、構文は同じですが、Bashはその中で変数をサポートしません。3seqfor{1..3}

したがって、これは次のように書くことができます。

for z in $(seq $#) ; do ...                  # or 
for (( z=1 ; z <= $# ; z++ )) ; do ...

または、kshまたはzshで中括弧を使用します。

for z in {1..$#} ; do  ... 

変数を間接的に参照するには、${!var}Bashでvar保存する場所を使用できます。名前変数、例えば

echo "param number $z is ${!z}"

あるいは、スライス表記を使用することもできます$@(Bash / ksh / zshで動作する必要があります)。

echo "param number $z is ${@:z:1}"

ただし、実際にはfor x in "$@"値を繰り返すことをより慣用的に考えることができます。数字を追加することも非常に簡単で、シェル関連の機能は必要ありません。

i=1
for x in "$@" ; do 
    echo "param $i is $x"
    i=$((i+1))     
done

関連情報