Primero, tenga en cuenta que $@sin comillas no tiene sentido y no debe usarse. $@solo debe usarse entre comillas ( "$@") y en contextos de lista.
for i in "$@" califica como un contexto de lista, pero aquí, para recorrer los parámetros posicionales, la forma canónica, más portátil y más simple es:
for i
do something with "$i"
done
Ahora, para recorrer los elementos a partir del segundo, la forma canónica y más portátil es usar shift:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Después shift, lo que solía ser $1se ha eliminado de la lista (pero lo hemos guardado $first_arg) y lo que solía estar $2ahora está dentro $1. Los parámetros posicionales se han desplazado 1 hacia la izquierda (se usa shift 2para cambiar por 2 ...). Básicamente, nuestro bucle se repite desde lo que solía ser el segundo argumento hasta el último.
Con bash(y zshy ksh93, pero eso es todo), una alternativa es hacer:
for i in "${@:2}"
do something with "$i"
done
Pero tenga en cuenta que no es una shsintaxis estándar, por lo que no debe usarse en un script que comience con #! /bin/sh -.
En zsho yash, también puedes hacer:
for i in "${@[3,-3]}"
do something with "$i"
done
pasar del 3er al 3er último argumento.
En zsh, $@también se conoce como la $argvmatriz. Entonces, para resaltar elementos desde el principio o el final de las matrices, también puede hacer:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shifttambién se puede escribir 1=()en zsh)
En bash, solo puede asignar a los $@elementos con la función setincorporada, por lo que sacar 3 elementos del final, sería algo así como:
set -- "${@:1:$#-3}"
Y para pasar del 3 al 3 último:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXY, para hacer estallar los últimos 3 elementos de "$@", necesitaría usar un bucle:
n=$(($# - 3))
for arg do
[ "$n" -gt 0 ] && set -- "$@" "$arg"
shift
n=$((n - 1))
done
for ((i=2; i<=$#; i++)); do something with "${!i}"; doneCreo que quieres el
shiftincorporado. Renombra$2a$1,$3a$2, etc.Me gusta esto:
fuente
forciclo, luego simplemente recorre $ @ normalmente. Después de lashiftllamada, $ @ debería serarg2_1 arg2_2 arg2_3...Siempre existe el enfoque del hombre de las cavernas:
Esto deja
$@intacto (en caso de que quiera usarlo más tarde), y simplemente recorre cada argumento, pero no procesa el primero.fuente
En bash también puedes escribir ese ciclo con indexación explícita:
Esto itera sobre todos los argumentos desde el segundo hasta el último. Si desea excluir el último argumento, simplemente haga esto
y si solo quieres tomar cualquier otro argumento, escríbelo como
La historia detrás de esto es la versión aritmética de la
forconstrucción , combinada con el conteo de argumentos$#y la indirección variable${…}.Una buena aplicación es que puede usar esto para decidir, dentro del ciclo, si una opción dada tomará el argumento que le sigue como un valor. Si lo hace, incremente
i(por ejemplo, escribir: $((++i))) para consumir el siguiente valor y omítalo durante la iteración.fuente