Comandi in loop in Bash

Comandi in loop in Bash

Eseguire lo stesso comando su tanti file dello stesso tipo è noioso, e come ogni cosa noiosa è meglio farla eseguire ad una macchina. Per fortuna la shell bash ci permette di creare dei loop di comandi in modo facilissimo usando le keyword for, do e done.

Vediamo ad esempio come visualizzare tutti i file di testo della directory corrente separandoli con una riga che contenga il loro nome:


$ ls
file.csv  newfile.csv  testo1.txt  testo2.txt
$ for i in *.txt; do echo "### File: $i ###"; cat "$i"; done
### File: testo1.txt ###

Questo è il file di testo numero uno.
Ciao!

### File: testo2.txt ###

Questo invece è il file di testo numero due.

Riciao.
$ 

La sintassi in dettaglio del loop è la seguente:


for <nome variabile> in <insieme di elementi> 
do <comandi da eseguire su ogni elemento - uso nome vatiabile  per identificare l'elemento>
done

Il ciclo può essere scritto su una sola riga, separando i vari segmenti for/do/done con ;, oppure posso digitarlo riga per riga e in questo caso la bash si accorgerà che sto scrivendo un loop e mi proporrà il prompt >. Esempio:


$ for i in *.txt
> do
> echo "$i"
> done
testo1.txt
testo2.txt
$ 

L' <insieme di elementi> può essere specificato sia usando il globbing (.txt o access_.log, ecc.) oppure un effettivo insieme delimitato da parentesi graffe. Esempio:


$ for NUM in {1,2,3,4,5}; do echo $NUM; done 
1
2
3
4
5

Oppure può essere addirittura preso dall'output di un altro comando usando l'operatore $( ):


$ for f in $(grep -i "ciao" *); do echo $f; done 
testo1.txt:Ciao!
testo2.txt:Riciao.
$ 

Quindi l'uso dei loop può rendere estremamente facile una nutrita serie di compiti ripetitivi, dove ad esempio occorre lanciare lo stesso comando su una serie di file diversi. Un task lungo e noioso che diventa banale grazie alla potenza della shell!

Currently there are no comments, so be the first!