forループで$ 1 $ 2 ...などのパラメータを使用するには? [コピー]

forループで$ 1 $ 2 ...などのパラメータを使用するには? [コピー]

引数として提供された単語の発音をダウンロードするように設計された次のスクリプトがあります。

#!/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でもありませんでした(ただし、bashPOSIXモードでも他のほとんどのBourne様シェルで利用可能です)。

または以下より:

for arg in "$@"; do
  printf 'Something with "%s"\n' "$arg"
done

これはPOSIXですが、Bourneシェルまたはksh88にスペース文字が含まれていない場合、または$IFSBourneシェルの一部のバージョンに引数が含まれていない場合、または一部のシェル(一部のパラメータを含む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と同様に、変数に名前が格納されているパラメータの内容に展開されます。zshP

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

おすすめ記事