Come scrivo un ciclo for in bash
Domanda
Sto cercando il ciclo di base come:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
ma per bash.
Soluzione
Da questo sito:
for i in $(seq 1 10);
do
echo $i
done
Altri suggerimenti
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
Il colpo for
consiste in una variabile (l'iteratore) e un elenco di parole in cui l'iteratore ripeterà.
Quindi, se hai un elenco limitato di parole, inseriscile semplicemente nella seguente sintassi:
for w in word1 word2 word3
do
doSomething($w)
done
Probabilmente vuoi scorrere alcuni numeri, quindi puoi usare il comando seq
comando per generare un elenco di numeri per te:(da 1 a 100 per esempio)
seq 1 100
e usarlo nel ciclo FOR:
for n in $(seq 1 100)
do
doSomething($n)
done
Notare la $(...)
sintassi.È un comportamento bash, ti consente di passare l'output di un comando (nel nostro caso from seq
) ad un altro (il for
)
Questo è davvero utile quando devi scorrere tutte le directory in qualche percorso, ad esempio:
for d in $(find $somepath -type d)
do
doSomething($d)
done
Le possibilità sono infinite per generare le liste.
Bash 3.0+ può usare questa sintassi:
for i in {1..10} ; do ... ; done
..che evita di generare un programma esterno per espandere la sequenza (come seq 1 10
).
Naturalmente, questo ha lo stesso problema di for(())
soluzione, essere legato a bash e persino a una versione particolare (se questo è importante per te).
Prova il bash
aiuto integrato:
$ help for
for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
Di solito mi piace usare una leggera variante allo standard for loop.Lo uso spesso per eseguire un comando su una serie di host remoti.Approfitto dell'espansione delle parentesi graffe di bash per creare cicli for che mi consentano di creare cicli for non numerici.
Esempio:
Voglio eseguire il comando uptime sugli host frontend 1-5 e sugli host backend 1-3:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
In genere lo eseguo come comando a riga singola con punto e virgola alle estremità delle righe invece della versione più leggibile sopra.La considerazione chiave sull'utilizzo è che le parentesi graffe consentono di specificare più valori da inserire in una stringa (ad es.pre{foo,bar}post risulta in prefoopost, prebarpost) e consentire il conteggio/sequenze utilizzando i punti doppi (puoi utilizzare a..z ecc.).Tuttavia, la sintassi del doppio punto è una nuova funzionalità di bash 3.0;le versioni precedenti non lo supporteranno.
#! /bin/bash
function do_something {
echo value=${1}
}
MAX=4
for (( i=0; i<MAX; i++ )) ; {
do_something ${i}
}
Ecco un esempio che può funzionare anche nelle shell più vecchie, pur essendo efficiente per conteggi di grandi dimensioni:
Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'
Ma buona fortuna per fare cose utili all'interno awk
: Come posso utilizzare le variabili di shell in uno script awk?
se sei interessato solo a bash il comando "for(( ...))" presentata sopra è la migliore, ma se vuoi qualcosa di conforme a POSIX SH che funzioni su tutti gli Unice dovrai usare "expr" e " while", e questo perché "(())" o "seq " o "i=i+1" non sono così portatili tra le varie shell
Utilizzo sempre variazioni di questo per elaborare i file...
per i file in formato *.log;do echo "Fai cose con:$file";echo "Fai più cose con:$file";Fatto;
Se ciò che ti interessa è l'elaborazione di elenchi di file, esamina il file -execdir opzione per File.