it-swarm-ja.com

stdinのすべての変数をforループにリストするにはどうすればよいですか?

このコードを持っている:

#!/bin/bash
for i in $#; do echo ${$i}; done

ここで、$#はstdinからの変数の数である必要があり、次のようになります。

${$i}: bad substitution

echo $0; echo $1; echo ...を記述せずにそれらをリストする方法と、変数自体を変数に置き換える方法は? (これは、ループなどによる変数名の「構築」です)

3
Herdsman

argv []はstdinではありません。

通常の方法は、完全にインデックスを作成することを避け、を直接反復することです(基本的に、_for..in_が最初にどのように機能するか)。すべての引数を表す特別な「配列」変数は_"[email protected]"_です–はい、配列の拡張を正しく行うには引用符が必要です。

_for v in "[email protected]"; do
    echo "Got $v"
done
_

(これは_$*_でも引用符で囲まれていない_[email protected]_でも行わないでください。どちらもスペースを含む引数を台無しにするためです。)

ただし、doインデックスも必要な場合、bashの正しい「逆参照」構文は_${!i}_です。

_for (( i = 1; i <= $#; i++ )); do
    echo "Item $i is ${!i}"
done
_

(数値範囲を反復するために必要なCのような構文に注意してください。_for i in {1..10}_を使用して静的範囲を実行することは可能ですが、_{1..$#}_のような変数の場合は残念ながら機能しません参加します。ただし、余分なサブプロセスを気にしない場合は、for i in $(seq 1 $#)を使用できます。)

最後に、最も古い方法の1つは、引数のリストを繰り返しshiftすることです。

_while [ "${1+yes}" ]; do
    echo "Got $1"
    shift
done
_

_${var+string}_展開は、長さがゼロ以外の文字列をチェックする代わりに、変数が任意に設定であるかどうかをチェックするために使用されます。これは、より直接的なチェックに簡略化されている場合があります。長さゼロの引数がないことを100%確信している限り問題ありません。

_while [ "$1" ]; do
    echo "Got $1"
    shift
done
_
4
user1686
#!/bin/bash

for i in "[email protected]"; do echo "${i}"; done

例:

$ ./s.sh a b c 'white space'
a
b
c
white space
3