Successivo: Programma igawk, Precedente: Programma extract, Su: Programmi vari [Contenuti][Indice]
Il programma di utilità sed
è un editore di flusso,
ovvero un programma che legge un flusso di dati, lo modifica, e scrive il file
così modificato.
È spesso usato per fare modifiche generalizzate a un grosso file, o a un
flusso di dati generato da una pipeline di comandi.
Sebbene sed
sia un programma piuttosto complesso di suo, l’uso che
se ne fa solitamente è di effettuare delle sostituzioni globali attraverso
una pipeline:
comando1 < dati.originali | sed 's/vecchio/nuovo/g' | comando2 > risultato
Qui, ‘s/vecchio/nuovo/g’ chiede a sed
di ricercare la
regexp ‘vecchio’ in ogni riga di input e di sostituirla
dappertutto con il testo ‘nuovo’ (cioè, in tutte le occorrenze di
ciascuna riga). Questo è simile a quello che fa la funzione di awk
gsub()
(vedi la sezione Funzioni di manipolazione di stringhe).
Il programma seguente, awksed.awk, accetta almeno due argomenti dalla riga di comando: l’espressione da ricercare e il testo con cui rimpiazzarla. Ogni ulteriore argomento è considerato come un nome di file-dati da elaborare. Se non ne viene fornito alcuno, si usa lo standard input:
# awksed.awk --- fa s/pippo/pluto/g usando solo print # Ringraziamenti a Michael Brennan per l'idea function sintassi() { print "sintassi: awksed espressione rimpiazzo [file...]" > "/dev/stderr" exit 1 }
BEGIN { # valida argomenti if (ARGC < 3) sintassi()
RS = ARGV[1] ORS = ARGV[2] # non usare argomenti come nomi di file ARGV[1] = ARGV[2] = "" }
# guarda, mamma, senza mani! { if (RT == "") printf "%s", $0 else print }
Il programma fa assegnamento sulla capacità di gawk
di avere come
RS
una regexp,
e anche sul fatto che RT
viene impostato al testo che effettivamente
delimita il record (vedi la sezione Controllare come i dati sono suddivisi in record).
L’idea è di usare RS
come espressione da ricercare. gawk
automaticamente imposta $0
al testo che compare tra due corrispondenze
all’espressione di ricerca.
Questo è appunto il testo che vogliamo conservare inalterato. Quindi,
impostando ORS
al testo che si vuole sostituire, una semplice
istruzione print
scrive il testo che si vuole mantenere, seguito dal
testo che si vuole invece sostituire.
C’è un problema in questo schema, ossia cosa fare se l’ultimo record
non termina con un testo che corrisponde a RS
. Usando un’istruzione
print
incondizionatamente stampa il testo da sostituire, il che non
è corretto.
Tuttavia, se il file non termina con del testo che corrisponde a RS
,
RT
è impostata alla stringa nulla. In tal caso, si può stampare
$0
usando printf
(vedi la sezione Usare l’istruzione printf
per stampe sofisticate).
La regola BEGIN
gestisce la preparazione, controllando che ci sia
il numero giusto di argomenti e chiamando sintassi()
se c’è un problema.
Poi imposta RS
e ORS
dagli argomenti della riga di comando e
imposta ARGV[1]
e ARGV[2]
alla stringa nulla, per impedire che
vengano considerati dei nomi-file
(vedi la sezione Usare ARGC
e ARGV
).
La funzione sintassi()
stampa un messaggio di errore ed esce.
Per finire, l’unica regola gestisce lo schema di stampa delineato più sopra,
usando print
o printf
come richiesto, a seconda del valore di
RT
.
Successivo: Programma igawk, Precedente: Programma extract, Su: Programmi vari [Contenuti][Indice]