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: たとえば$1でforループなしでスクリプトを書くと、正しく動作しますが、同時に多くのファイルをダウンロードしたいのです

答え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 ですが、 に$IFSスペース文字が含まれていない場合、または引数がない場合の一部の Bourne シェルのバージョン、または引数がなくオプションが有効になっている一部のシェル ( の一部のバージョンを含むbash) では、 Bourne シェルまたは ksh88 では-u正しく動作しません。

あるいは

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

これは POSIX と Bourne ですが、非常に古い ash ベースのシェルでは動作しません。私は個人的にはこれを無視して、この構文を使用しています。これが最も読みやすいと思うからです。また、私が書いたコードがこのような難解なシェルで解釈されることは期待していません。

詳細情報:


$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

答え2

私は を使用しますshift。これは[ -n "$1" ]、arg-1 が空でない限り、ループを続けることを意味します。

#! /bin/bash 
while [ -n "$1" ]; do
  echo "$1"
  wget "https://ssl.gstatic.com/dictionary/static/sounds/de/0/$1.mp3"
  shift
done

答え3

最も簡単な方法

#!/bin/bash
for i
do
 echo $i
done

そして走る

./a.sh personality brave selfish

そしてこれが標準出力に出力されるものです

personality
brave
selfish

関連情報