Successivo: , Precedente: , Su: Cloni   [Contenuti][Indice]


11.2.5 Inviare l’output su più di un file

Il programma tee è noto come pipe fitting (tubo secondario). tee copia il suo standard input al suo standard output e inoltre lo duplica scrivendo sui file indicati nella riga di comando. La sua sintassi è la seguente:

tee [-a] file

L’opzione -a chiede a tee di aggiungere in fondo al file indicato, invece che riscriverlo dall’inizio.

La regola BEGIN dapprima fa una copia di tutti gli argomenti presenti sulla riga di comando, in un vettore di nome copia. ARGV[0] non serve, e quindi non viene copiato. tee non può usare ARGV direttamente, perché awk tenta di elaborare ogni nome-file in ARGV come dati in input.

Se il primo argomento è -a, la variabile flag append viene impostata a vero, e sia ARGV[1] che copia[1] vengono cancellati. Se ARGC è minore di due, nessun nome-file è stato fornito, e tee stampa un messaggio di sintassi ed esce. Infine, awk viene obbligato a leggere lo standard input impostando ARGV[1] al valore "-" e ARGC a due:

# tee.awk --- tee in awk
#
# Copia lo standard input a tutti i file di output indicati.
# Aggiunge in fondo se viene data l'opzione -a.
#
BEGIN {
    for (i = 1; i < ARGC; i++)
        copia[i] = ARGV[i]

    if (ARGV[1] == "-a") {
        append = 1
        delete ARGV[1]
        delete copia[1]
        ARGC--
    }
    if (ARGC < 2) {
        print "sintassi: tee [-a] file ..." > "/dev/stderr"
        exit 1
    }
    ARGV[1] = "-"
    ARGC = 2
}

La seguente regola è sufficiente da sola a eseguire il lavoro. Poiché non è presente alcun criterio di ricerca, la regola è eseguita per ogni riga di input. Il corpo della regola si limita a stampare la riga su ogni file indicato nella riga di comando, e poi sullo standard output:

{
    # spostare l'if fuori dal ciclo ne velocizza l'esecuzione
    if (append)
        for (i in copia)
            print >> copia[i]
    else
        for (i in copia)
            print > copia[i]
    print
}

È anche possibile scrivere il ciclo così:

for (i in copia)
    if (append)
        print >> copia[i]
    else
        print > copia[i]

Questa forma è più concisa, ma anche meno efficiente. L’‘if’ è eseguito per ogni record e per ogni file di output. Duplicando il corpo del ciclo, l’‘if’ è eseguito solo una volta per ogni record in input. Se ci sono N record in input e M file di output, il primo metodo esegue solo N istruzioni ‘if’, mentre il secondo esegue N*M istruzioni ‘if’.

Infine, la regola END fa pulizia, chiudendo tutti i file di output:

END {
    for (i in copia)
        close(copia[i])
}

Successivo: , Precedente: , Su: Cloni   [Contenuti][Indice]