Successivo: FD speciali, Precedente: Printf, Su: Stampare [Contenuti][Indice]
print
e printf
Finora, l’output di print
e printf
è stato diretto
verso lo standard output,
che di solito è lo schermo. Sia print
che printf
possono
anche inviare il loro output in altre direzioni.
È quel che si chiama ridirezione.
NOTA: Quando si specifica --sandbox (vedi la sezione Opzioni sulla riga di comando), la ridirezione dell’output verso file, pipe e coprocessi non è consentita.
Una ridirezione è posta dopo l’istruzione print
o printf
.
Le ridirezioni in awk
sono scritte come le ridirezioni nei
comandi della shell, l’unica differenza è che si trovano all’interno di
un programma awk
.
Ci sono quattro forme di ridirezione dell’output:
output scritto su un file,
output aggiunto in fondo a un file,
output che fa da input a un altro comando (usando una pipe) e
output diretto a un coprocesso.
Vengono descritti per l’istruzione print
,
ma funzionano allo stesso modo per printf
:
print elementi > output-file
Questa ridirezione stampa gli elementi nel file di output chiamato
output-file. Il nome-file output-file può essere
una qualsiasi espressione. Il suo valore è trasformato in una stringa e
quindi usato come
nome-file (vedi la sezione Espressioni).
Quando si usa questo tipo di ridirezione, il file output-file viene
cancellato prima che su di esso sia stato scritto il primo record in uscita.
Le successive scritture verso lo stesso file output-file non cancellano
output-file, ma continuano ad aggiungervi record.
(Questo comportamento è differente da quello delle ridirezioni usate negli
script della shell.)
Se output-file non esiste, viene creato. Per esempio, ecco
come un programma awk
può scrivere una lista di nomi di persone
su un file di nome lista-nomi, e una lista di numeri telefonici
su un altro file di nome lista-telefoni:
$ awk '{ print $2 > "lista-telefoni" > print $1 > "lista-nomi" }' mail-list $ cat lista-telefoni -| 555-5553 -| 555-3412 … $ cat lista-nomi -| Amelia -| Anthony …
Ogni file in output contiene un nome o un numero su ogni riga.
print elementi >> output-file
Questa ridirezione stampa gli elementi in un file di output preesistente,
di nome output-file. La differenza tra questa ridirezione e quella
con un solo ‘>’ è che il precedente contenuto (se esiste) di
output-file non viene cancellato. Invece, l’output di awk
è
aggiunto in fondo al file.
Se output-file non esiste, viene creato.
print elementi | comando
È possibile inviare output a un altro programma usando una pipe invece di inviarlo a un file. Questa ridirezione apre una pipe verso comando, e invia i valori di elementi, tramite questa pipe, a un altro processo creato per eseguire comando.
L’argomento comando, verso cui è rivolta la ridirezione, è in realtà
un’espressione
awk
. Il suo valore è convertito in una stringa il cui contenuto
costituisce un comando della shell che deve essere eseguito. Per esempio,
il seguente programma produce due file, una lista non ordinata di nomi di
persone e una lista ordinata in ordine alfabetico inverso:
awk '{ print $1 > "nomi.non.ordinati" comando = "sort -r > nomi.ordinati" print $1 | comando }' mail-list
La lista non ordinata è scritta usando una ridirezione normale, mentre
la lista ordinata è scritta inviando una pipe in input al programma
di utilità sort
.
Il prossimo esempio usa la ridirezione per inviare un messaggio alla
mailing list bug-sistema
. Questo può tornare utile se si hanno
problemi con uno script awk
eseguito periodicamente per la
manutenzione del sistema:
report = "mail bug-sistema" print("Script awk in errore:", $0) | report print("al record numero", FNR, "di", NOME_FILE) | report close(report)
La funzione close()
è stata chiamata perché è una buona idea chiudere
la pipe non appena tutto l’output da inviare alla pipe è stato
inviato. Vedi la sezione Chiudere ridirezioni in input e in output
per maggiori informazioni.
Questo esempio illustra anche l’uso di una variabile per rappresentare
un file o un comando; non è necessario usare sempre
una costante stringa. Usare una variabile è di solito una buona idea,
perché (se si vuole riusare lo stesso file o comando)
awk
richiede che il valore della stringa sia sempre scritto
esattamente nello stesso modo.
print elementi |& comando
Questa ridirezione stampa gli elementi nell’input di comando.
La differenza tra questa ridirezione e quella
con la sola ‘|’ è che l’output da comando
può essere letto tramite getline
.
Quindi, comando è un coprocesso, che lavora in parallelo al
programma awk
, ma è al suo servizio.
Questa funzionalità è un’estensione gawk
, e non è disponibile in
POSIX awk
.
Vedi la sezione Usare getline
da un coprocesso,
per una breve spiegazione.
Comunicazioni bidirezionali con un altro processo
per un’esposizione più esauriente.
Ridirigere l’output usando ‘>’, ‘>>’, ‘|’ o ‘|&’ richiede al sistema di aprire un file, una pipe o un coprocesso solo se il particolare file o comando che si è specificato non è già stato utilizzato in scrittura dal programma o se è stato chiuso dopo l’ultima scrittura.
È un errore comune usare la ridirezione ‘>’ per la prima istruzione
print
verso un file, e in seguito usare ‘>>’ per le successive
scritture in output:
# inizializza il file print "Non v'allarmate" > "guida.txt" … # aggiungi in fondo al file print "Evitate generatori di improbabilità" >> "guide.txt"
Questo è il modo in cui le ridirezioni devono essere usate lavorando
con la shell. Ma in awk
ciò non è necessario. In casi di questo
genere, un programma dovrebbe
usare ‘>’ per tutte le istruzioni print
, perché il file di
output è aperto una sola volta.
(Usando sia ‘>’ che ‘>>’ nello stesso programma, l’output è prodotto
nell’ordine atteso.
Tuttavia il mischiare gli operatori per lo stesso file è sintomo di uno
stile di programmazione inelegante, e può causare confusione in chi legge
il programma.)
Come visto in precedenza
(vedi la sezione Cose importanti da sapere riguardo a getline
),
molte
tra le più vecchie implementazioni di
awk
limitano il numero di pipeline che un programma
awk
può mantenere aperte a una soltanto! In gawk
, non c’è
un tale limite. gawk
consente a un programma di
aprire tante pipeline quante ne consente il sistema operativo su cui
viene eseguito.
Inviare pipe alla
sh
Una maniera particolarmente efficace di usare la ridirezione è quella di
preparare righe di comando da passare
come pipe alla shell,
{ printf("mv %s %s\n", $0, tolower($0)) | "sh" } END { close("sh") } La funzione Vedi la sezione Stringhe con apici da passare alla shell per una funzione che può essere utile nel generare righe di comando da passare alla shell. |
Successivo: FD speciali, Precedente: Printf, Su: Stampare [Contenuti][Indice]