如何在 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 的 shell 中,它是:

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(儘管可以在大多數其他類似 Bourne 的 shell 中使用,bash甚至包括 POSIX 模式)

或比:

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

這是 POSIX,但在不包含空格字元時在 Bourne shell 或 ksh88 中無法正常工作$IFS,或者在沒有參數時在某些版本的Bourne shell 中無法正常工作,或者在沒有參數時在某些shell(包括某些版本的bash)中無法正常工作參數並且該-u選項已啟用。

或者比

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

這是 POSIX 和 Bourne,但不能在非常舊的基於 ash 的 shell 中工作。我個人會忽略這一點並自己使用該語法,因為我發現它是最清晰的,並且不希望我編寫的任何程式碼最終都會被這樣一個神秘的 shell 解釋。

更多資訊請見:


現在,如果您確實想$i循環[1..$#]並存取相應的元素,您可以執行以下操作:

在任何 POSIX shell 中:

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

相關內容