Title: Separazione delle parole nella shell
Author: Sandro Tosi
Last modified: 2007-09-01
Cerchiamo di capire come bash separi le parole tra loro; questo ci
tornera` utile soprattutto in fase di scrittura di shell script.
La shell esamina il contenuto di espansioni di parametri, sostituzione
di comandi, ed espansioni aritmetiche non racchiusi tra doppi apici
per la separazione in parole.
Bash utilizza ogni carattere contenuto nella variabile IFS (Internal
Field Separator) come delimitatore, e separa il risultato delle
espansioni precedenti in parole usando quei caratteri.
Il valore di default e` ``<space><tab><newline>''; e` possibile
specificare altri valori per IFS, valorizzando la variabile
opportunamente. Se IFS e` nulla (IFS="" o IFS=''), non avviene alcuna
separazione in parole.
Si faccia attenzione a cambiare IFS in quanto questo potrebbe portare
a diversi effetti collaterali; in ogni caso, per ripristinare il
valore di default si puo` eseguire:
IFS=' \t\n'
Ecco un esempio che puo` aiutare a comprendere l'utilizzo di IFS:
$ a=w:x:y:z
$ cat $a
cat: w:x:y:z: No such file or directory
$ IFS=":"
$ cat $a
cat: w: No such file or directory
cat: x: No such file or directory
cat: y: No such file or directory
cat: z: No such file or directory
Nella prima esecuzione di `cat', la shell espande la variabile "a" ed
interpreta la stringa "w:x:y:z" come una singola parola e cosi` viene
passata come argomento a `cat'. Dopo, quando IFS e` valorizzata a ":",
l'espansione di $a fa si` che la shell separi la stringa in quattro
parole, ed ognuna di esse diventi parametro di `cat'.
Questo meccanismo funziona solo se c'e` espansione: se non c'e`
espansione, allora non c'e` nemmeno separazione in parole.
Se IFS non e` settata, solo i caratteri "spazio" e "tab" funzioneranno
da separatori.
Un esempio tipico in cui si ha necessita` di cambiare il valore di IFS
e` quando si vuole lavorare "per righe":
$ cat test.txt
prima linea del file
seconda linea del file
$ for token in $(cat test.txt); do echo $token ; done
$(cat test.txt) viene espanso in "prima linea del file seconda linea
del file" (in quanto l'espansione elimina i ritorni a capo), e questa
stringa verra` spezzata per il separatore IFS (di default impostato al
carattere spazio) e quindi il ciclo stampera` una parola alla volta.
Se invece si ha necessita` di lavorare riga-per-riga, si deve
impostare IFS in uno dei seguenti modi:
IFS=$'\n'
oppure
IFS='<premere return..>
'
Il ciclo precedente, a questo punto, stampera` una linea alla volta. |