Pertama, perhatikan bahwa $@
tanpa tanda kutip tidak masuk akal dan tidak boleh digunakan. $@
seharusnya hanya digunakan dikutip ( "$@"
) dan dalam konteks daftar.
for i in "$@"
memenuhi syarat sebagai konteks daftar, tetapi di sini, untuk mengulang parameter posisi, bentuk kanonik, paling portabel dan lebih sederhana adalah:
for i
do something with "$i"
done
Sekarang, untuk mengulang elemen mulai dari yang kedua, cara kanonik dan paling portabel adalah dengan menggunakan shift
:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Setelah itu shift
, apa yang dulu $1
telah dihapus dari daftar (tapi kami telah menyimpannya $first_arg
) dan apa yang dulu ada di $2
sekarang $1
. Parameter posisi telah digeser 1
posisi ke kiri (gunakan shift 2
untuk menggeser oleh 2 ...). Jadi pada dasarnya, perulangan kita adalah perulangan dari apa yang dulunya adalah argumen kedua ke argumen terakhir.
Dengan bash
(dan zsh
dan ksh93
, tapi hanya itu), alternatifnya adalah dengan melakukan:
for i in "${@:2}"
do something with "$i"
done
Tetapi perhatikan bahwa itu bukan sh
sintaks standar sehingga tidak boleh digunakan dalam skrip yang dimulai #! /bin/sh -
.
Di zsh
atau yash
, Anda juga dapat melakukan:
for i in "${@[3,-3]}"
do something with "$i"
done
untuk mengulang dari argumen terakhir ke 3 ke 3.
In zsh
, $@
juga dikenal sebagai $argv
array. Jadi untuk memunculkan elemen dari awal atau akhir array, Anda juga dapat melakukan:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shift
dapat juga ditulis 1=()
dalam zsh
)
Di bash
, Anda hanya dapat menetapkan $@
elemen dengan set
builtin, jadi untuk menghilangkan 3 elemen pada akhirnya, itu akan menjadi seperti:
set -- "${@:1:$#-3}"
Dan untuk mengulang dari 3 ke 3 terakhir:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXly, untuk memunculkan 3 elemen terakhir "$@"
, Anda harus menggunakan loop:
n=$(($# - 3))
for arg do
[ "$n" -gt 0 ] && set -- "$@" "$arg"
shift
n=$((n - 1))
done
for ((i=2; i<=$#; i++)); do something with "${!i}"; done
Saya pikir Anda ingin
shift
builtin. Itu mengubah nama$2
menjadi$1
,$3
untuk$2
, dll.Seperti ini:
sumber
for
loop, maka Anda hanya mengulang $ $ secara normal. Setelahshift
panggilan, $ @ seharusnyaarg2_1 arg2_2 arg2_3...
Selalu ada pendekatan manusia gua:
Ini
$@
tetap utuh (jika Anda ingin menggunakannya nanti), dan cukup simpulkan setiap argumen, tetapi tidak memproses yang pertama.sumber
Di bash Anda juga bisa menulis loop itu dengan pengindeksan eksplisit:
Ini mengulangi semua argumen dari yang kedua ke yang terakhir. Jika Anda ingin mengecualikan argumen terakhir, cukup buat ini
dan jika Anda hanya ingin mengambil setiap argumen lain, tulis sebagai
Kisah di balik ini adalah versi aritmatika dari
for
builtin , dikombinasikan dengan argumen-count$#
dan tipuan variabel${…}
.Satu aplikasi bagus adalah Anda bisa menggunakan ini untuk memutuskan, di dalam loop, apakah opsi yang diberikan akan mengambil argumen yang mengikutinya sebagai nilai. Jika ya, tambahkan
i
(misalnya menulis: $((++i))
) untuk menggunakan nilai berikutnya dan lewati selama iterasi.sumber