Tout d'abord, notez que $@
sans guillemets n'a pas de sens et ne doit pas être utilisé. $@
doit être utilisé uniquement entre guillemets ( "$@"
) et dans des contextes de liste.
for i in "$@"
qualifie comme un contexte de liste, mais ici, pour boucler sur les paramètres de position, la forme canonique, la plus portable et la plus simple est:
for i
do something with "$i"
done
Maintenant, pour boucler sur les éléments à partir du second, la manière la plus canonique et la plus portable est d’utiliser shift
:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Après shift
, ce qui était auparavant $1
a été supprimé de la liste (mais nous l'avons enregistré $first_arg
) et ce qui était auparavant $2
est maintenant $1
. Les paramètres de position ont été décalés 1
à gauche (utilisez shift 2
pour décaler de 2 ...). Donc, fondamentalement, notre boucle boucle de ce qui était le deuxième argument au dernier.
Avec bash
(et zsh
et ksh93
, mais c'est tout), une alternative est de faire:
for i in "${@:2}"
do something with "$i"
done
Mais notez que ce n'est pas une sh
syntaxe standard et qu'il ne faut donc pas l'utiliser dans un script qui commence par #! /bin/sh -
.
En zsh
ou yash
, vous pouvez aussi faire:
for i in "${@[3,-3]}"
do something with "$i"
done
faire une boucle du 3ème au 3ème dernier argument.
Dans zsh
, $@
est également connu sous le nom de $argv
tableau. Donc, pour faire apparaître des éléments au début ou à la fin des tableaux, vous pouvez également faire:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shift
peut également être écrit 1=()
dans zsh
)
Dans bash
, vous ne pouvez affecter que les $@
éléments avec la fonction set
intégrée. Par conséquent, pour extraire 3 éléments à la fin, cela ressemblerait à quelque chose comme:
set -- "${@:1:$#-3}"
Et pour boucler du 3 au 3 dernier:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXly, pour faire apparaître les 3 derniers éléments de "$@"
, vous devez utiliser une boucle:
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
Je pense que vous voulez la fonction
shift
intégrée. Il renomme$2
à$1
,$3
à$2
, etc.Comme ça:
la source
for
boucle, puis vous parcourez simplement $ @ normalement. Après l'shift
appel, $ @ devrait êtrearg2_1 arg2_2 arg2_3...
Il y a toujours l'approche homme des cavernes:
Cela laisse
$@
intact (au cas où vous voudriez l'utiliser plus tard), et boucle simplement sur chaque argument, mais ne traite pas le premier.la source
En bash, vous pouvez également écrire cette boucle avec une indexation explicite:
Ceci itère sur tous les arguments du deuxième au dernier. Si vous voulez exclure le dernier argument à la place, faites simplement ceci
et si vous voulez seulement prendre tous les autres arguments, écrivez-le comme
L'histoire derrière ceci est la version arithmétique de la commande
for
intégrée , combinée au nombre d' arguments$#
et à l' indirection de variable${…}
.Une bonne application est que vous pouvez utiliser ceci pour décider, dans la boucle, si une option donnée prendra l'argument qui le suit comme valeur. Si c'est le cas, incrémentez
i
(par exemple en écrivant: $((++i))
) pour utiliser la valeur suivante et ignorez-la lors de l'itération.la source