引数として提供された単語の発音をダウンロードするように設計された次のスクリプトがあります。
#!/bin/bash
m=$#
for ((i=1;i<=m;i++));do
echo $i
#wget https://ssl.gstatic.com/dictionary/static/sounds/de/0/"$i".mp3
done
このコマンドで実行すると
./a.sh personality brave selfish
標準出力として印刷する必要があります。
personality
brave
selfish
しかし印刷されます
1
2
3
この問題を解決するのに役立ちますか?
ps:forループなしで$ 1でスクリプトを書くとうまくいきますが、同時に多くのファイルをダウンロードしたいと思います。
ベストアンサー1
Bourneに似たシェルでは、次のようになります。
for arg
do printf 'Something with "%s"\n' "$arg"
done
for
つまり、位置引数($1
、...)はデフォルトで繰り返されます$2
(一部を指定しない場合in ...
)。
これは以下より移植性に優れています。
for arg; do
printf 'Something with "%s"\n' "$arg"
done
2016バージョンの標準以前はPOSIXでもBourneでもありませんでした(ただし、bash
POSIXモードでも他のほとんどのBourne様シェルで利用可能です)。
または以下より:
for arg in "$@"; do
printf 'Something with "%s"\n' "$arg"
done
これはPOSIXですが、Bourneシェルまたはksh88にスペース文字が含まれていない場合、または$IFS
Bourneシェルの一部のバージョンに引数が含まれていない場合、または一部のシェル(一部のパラメータを含むbash
)では正しく機能しません。 )この-u
オプションが有効になります。
または
for arg do
printf 'Something with "%s"\n' "$arg"
done
これはPOSIXとBourneですが、非常に古い再ベースのシェルでは動作しません。私は個人的にこれを無視し、その構文を直接使用します。なぜなら、私はそれが最も明確であると思い、私が書いたコードがそのような不思議なシェルによって解釈されることを望まないからです。
詳しくは以下をご覧ください。
これで、その要素を$i
繰り返してアクセスしたい場合は、次のことができます。[1..$#]
POSIXシェルでは:
i=1
for arg do
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
または:
i=1
while [ "$i" -le "$#" ]; do
eval "arg=\${$i}"
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
またはbash
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${!i}"
done
${!i}
間接変数の拡張です。つまり、パラメータ拡張フラグi
と同様に、変数に名前が格納されているパラメータの内容に展開されます。zsh
P
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${(P)i}"
done
では、配列を介して位置パラメータにアクセスするzsh
こともできます$argv
(のようにcsh
)。
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: $argv[i]"
done