[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]
Capita spesso la necessità di scandire un elenco di parole allo scopo di eseguire uno o più comandi nell'ambito di tale scansione, utilizzando le parole stesse come argomenti dei comandi. Per fare un esempio di cosa si intende con questo, si pensi a un elenco di nomi di file, a partire dal quale si vuole ottenere l'esecuzione di un comando, una volta per ognuno di questi nomi. Questo tipo di scansione si esegue facilmente realizzando dei piccoli programmi, in forma di script, oppure si utilizza il programma xargs quando ciò che si intende fare non è troppo complesso.
Il comando for di una shell Bourne (tipicamente Bash) scandisce una serie di elementi, in corrispondenza dei quali esegue una lista di comandi.
for variabile in valore...
do
lista_di_comandi
done
L'elenco di parole che segue in viene espanso, generando una lista di elementi. La variabile indicata dopo for viene posta ogni volta al valore di ciascun elemento di questa lista e la lista di comandi che segue do viene eseguita ogni volta di conseguenza.
Per esempio, il comando seguente aggiunge a ogni file l'estensione .txt
, senza nemmeno bisogno di realizzare uno script:
$
for a in * ; do mv $a $a.txt ; done
Volendo vedere meglio questo esempio in uno script, basta trasformarlo nel modo seguente:
#!/bin/sh for a in * do mv $a $a.txt done
L'elenco di parole che segue in, può anche essere contenuto in una variabile di ambiente. Per esempio, si osservi lo script seguente, che in pratica svolge la stessa operazione già descritta, ma raccogliendo prima l'elenco dei nomi attraverso il comando ls:
#!/bin/sh elenco=`ls` for a in $elenco do mv $a $a.txt done
L'esempio seguente è più complesso, perché consente di cambiare l'estensione dei file, non solo di aggiungerne una. In particolare, si vuole sostituire l'estensione .testo
con .txt
:
#!/bin/sh for a in *.testo do mv $a `echo $a | sed s/\.testo$/\.txt/` done
In pratica, sed riceve dallo standard input il nome del file, nel quale trova la stringa finale .testo e la sostituisce con .txt (SED è descritto nel capitolo 318).
xargs (1) è un programma di servizio di cui si tende a non comprendere immediatamente l'utilità. Volendo sintetizzare, xargs estrae dallo standard input delle «parole», intese come sequenze di caratteri e simboli separati da spazi o da interruzioni di riga, per utilizzarle come argomenti di un comando che viene avviato più volte, in base alla quantità di queste parole disponibili.
La situazione più banale è quella rappresentata dal comando seguente:
$
xargs echo
Volendo ottenere lo stesso risultato con uno script di shell, si potrebbe tradurre nel codice seguente:
#!/bin/sh ELENCO=`cat` RISULTATO="" for a in $ELENCO do RISULTATO="$RISULTATO $a" done echo $RISULTATO
In pratica, viene letto tutto lo standard input (salvo limiti di memoria); quanto inserito viene scandito e si aggiunge ogni elemento a una lista separata solo da uno spazio singolo; alla fine viene emessa questa lista attraverso lo standard output.
Si osservi che utilizzando xargs senza alcun argomento, si ottiene comunque questo risultato in modo predefinito. |
$
xargs echo
[Invio]
uno due tre quattro
[Invio]
cinque sei
[Invio]
sette
[Invio]
[Ctrl+d]
uno due tre quattro cinque sei sette
Quello che si vede sopra è un esempio di come può comportarsi xargs usato in questo modo. Benché sia questo il comportamento predefinito, di solito occorre specificare in che modo xargs debba leggere lo standard input:
xargs [opzioni] [comando [argomenti_del_comando]]
L'opzione che definisce in che modo debba comportarsi xargs nei confronti dello standard input va scelta tra quelle descritte nell'elenco che segue. È importante comprendere che non serve a nulla indicare più di una di queste opzioni, dal momento che solo l'ultima viene presa in considerazione.
--replace[=stringa_da_rimpiazzare] | -i[stringa_da_rimpiazzare]
In questo modo, si stabilisce che deve essere presa in considerazione una riga alla volta di ciò che proviene dallo standard input; tuttavia, questa riga non viene fornita automaticamente come argomento finale del comando, al contrario va utilizzato un simbolo per collocare tali informazioni. Si osservi l'esempio seguente:
$
xargs -iciao echo ciao
[Invio]
uno due tre quattro
[Invio]
uno due tre quattro
cinque sei
[Invio]
cinque sei
sette
[Invio]
sette
[Ctrl+d]
Come si vede, viene stabilito che la stringa ciao serve a stabilire in che punto deve essere collocato ciò che si estrae dallo standard input. Dal momento che l'indicazione di tale stringa è facoltativa, si intende che esista anche una stringa predefinita: si tratta di {}. Pertanto, la stessa cosa già mostrata, poteva essere ottenuta con il comando seguente:
$
xargs -i echo "{}"
--max-lines[=n_righe] | -l[n_righe]
Si stabilisce di utilizzare la quantità di righe non vuote indicata come argomento per ogni avvio del comando. Tuttavia, se una riga termina con uno spazio orizzontale (uno spazio vero e proprio o un carattere di tabulazione), si intende che questa non sia terminata e continui nella riga successiva. Si osservi l'esempio seguente che mostra proprio questo particolare:
$
xargs -l2 echo
[Invio]
uno due
[Invio]
tre quattro cinque
[Invio]
uno due tre quattro cinque
sei sette
[Invio]
otto
[Invio]
nove dieci
[Invio]
sei sette otto nove dieci
undici
[Invio]
[Ctrl+d]
undici
Si può osservare che dopo la parola «sette» c'è uno spazio che crea una continuazione con la riga successiva.
L'indicazione del numero delle righe è facoltativo, perché in sua mancanza si fa riferimento a una sola riga.
--max-args[=n_parole] | -n[n_parole]
Si stabilisce di utilizzare la quantità di parole indicata come argomento per ogni avvio del comando. Si osservi l'esempio seguente:
$
xargs -n2 echo
[Invio]
uno due tre
[Invio]
uno due
quattro cinque
[Invio]
tre quattro
[Ctrl+d]
cinque
Quelle che qui sono state chiamate «parole», ovvero le sequenze di caratteri che vengono prese in considerazione come elementi singoli, sono distinte in base all'uso di spazi, caratteri di tabulazione e interruzioni di riga. Queste parole possono anche essere delimitate tra apici singoli o doppi (' e "), per esempio per includere degli spazi di qualche tipo; inoltre è possibile utilizzare il carattere \ per confermare il valore letterale del carattere successivo.
Oltre all'opzione che specifica la modalità di lettura e scansione dello standard input se ne possono usare altre, tra le quali quelle descritte nel seguito.
--eof[=stringa_di_fine_file] | -e[stringa_di_fine_file]
In condizioni normali, la fine del file viene riconosciuta al termine dello stesso. Negli esempi mostrati in precedenza, veniva terminato l'inserimento dei dati attraverso la combinazione [Ctrl+d], proprio in questo senso. Tuttavia, xargs riconosce una stringa particolare, individuata come parola isolata, con lo scopo di indicare la fine dei dati da prendere in considerazione. In condizioni normali, questa stringa è _, che così assume un ruolo particolare. Con questa opzione, è possibile stabilire una stringa diversa per concludere i dati da scandire.
--interactive | -p
Con questa opzione, si fa in modo che xargs chieda conferma prima di eseguire qualsiasi comando. La conferma avviene inserendo la lettera y e premendo successivamente [Invio]. Qualunque altra cosa annulla il comando proposto.
--verbose | -t
Mostra i comandi prima di eseguirli.
--max-chars[=n_max_caratteri] | -s[n_max_caratteri]
Permette di stabilire un limite massimo per la lunghezza dei comandi generati da xargs (si include tutto il comando generato, non solo gli argomenti che gli vengono forniti).
--exit | -x
In presenza di un comando che eccede la quantità di caratteri massima predefinita, o fissata con l'opzione -s, termina il funzionamento di xargs.
daniele @ swlibero.org
1) GNU findutils GNU GPL
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome scansione_di_parole.html
[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]