Innanzitutto, nota che $@senza virgolette non ha senso e non dovrebbe essere usato. $@dovrebbe essere usato solo tra virgolette ( "$@") e in contesti di lista.
for i in "$@" si qualifica come un contesto di elenco, ma qui, per passare in rassegna i parametri posizionali, la forma canonica, più portatile e più semplice è:
for i
do something with "$i"
done
Ora, per passare in rassegna gli elementi a partire dal secondo, il modo canonico e più portatile è usare shift:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Dopo shift, ciò che era $1stato rimosso è stato rimosso dall'elenco (ma lo abbiamo salvato in $first_arg) e quello che era in $2è ora $1. I parametri posizionali sono stati spostati 1 verso sinistra (usare shift 2per spostare di 2 ...). Quindi, in sostanza, il nostro ciclo sta passando da quello che era il secondo argomento all'ultimo.
Con bash(e zshe ksh93, ma questo è tutto), un'alternativa è fare:
for i in "${@:2}"
do something with "$i"
done
Ma nota che non è una shsintassi standard, quindi non dovrebbe essere usata in uno script che inizia con #! /bin/sh -.
In zsho yash, puoi anche fare:
for i in "${@[3,-3]}"
do something with "$i"
done
per passare dal 3o al 3o ultimo argomento.
In zsh, $@è anche noto come $argvarray. Quindi, per far apparire gli elementi dall'inizio o dalla fine delle matrici, puoi anche fare:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shiftpuò anche essere scritto 1=()in zsh)
In bash, puoi solo assegnare agli $@elementi con l' setintegrato, quindi per estrarre 3 elementi alla fine, sarebbe qualcosa del tipo:
set -- "${@:1:$#-3}"
E per passare dal 3 ° al 3 ° ultimo:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIX, per far apparire gli ultimi 3 elementi di "$@", avresti bisogno di usare un 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