Ci sono 2 modi per impostare awk vars dalla riga di comando?


10

Ho notato un awkesempio di O'Reilly (1997) che ha assegnato una variabile awk impostandola sulla riga di comando dopo il testo del programma. Funziona, ma non riesco a trovare questa sintassi in man / info awk . L'ho appena perso; è depresso ...? L'unica sintassi che ho visto nel manuale è l' -vopzione.

awk '/home/{print foo, bar}' foo="cat" bar="dog" /proc/$$/cmdline

Produzione: cat dog

Risposte:


11

In realtà è in POSIX awk(collegamento a POSIX 2008, credo anche nelle versioni precedenti). -vè descritto nella sezione Opzioni , l'altro modo è nella sezione Operandi .

C'è una differenza tra -ve passare i compiti alla fine con i nomi dei file:

  • Con -v:

La domanda deve garantire che l'argomento di assegnazione abbia la stessa forma di un operando di assegnazione. L'assegnazione della variabile specificata deve avvenire prima di eseguire il programma awk, comprese le azioni associate ai pattern BEGIN (se presenti). È possibile specificare più occorrenze di questa opzione.

  • Mescolato con i nomi dei file:

[...] Ciascuna di tali assegnazioni variabili deve avvenire appena prima dell'elaborazione del seguente file , se presente. Pertanto, un'assegnazione prima del primo argomento del file deve essere eseguita dopo le azioni BEGIN (se presenti), mentre un'assegnazione dopo l'ultimo argomento del file deve avvenire prima delle azioni END (se presenti). Se non ci sono argomenti sui file, le assegnazioni devono essere eseguite prima di elaborare l'input standard.

Esempio:

$ cat input 
hello
hello
$ awk -v var=one 'BEGIN{print var} /hello/{print var} END{print var}' \
    var=two input var=three input var=four
one
two
two
three
three
four

Wow! Ciò aggiunge alcuni punti di controllo interessanti ... è sicuramente utile. Grazie ...
Peter

1
Il mio iniziale "Wow!" è ancora valido, ma è stato temperato in qualche modo esaminando ulteriormente la risposta di Arcege ... L'ho provato con un file reale chiamato "var = three" ... awkho dato la precedenza al fatto che era un compito variabile ... Questo ha un corollario maggiore , cioè In tutti i casi in cui un nome di file ha questo modulo, verrà ignorato e la variabile verrà impostata ... Sembra che l'unico modo per evitare questo scontro sia assicurando che i nomi dei file per la directory di lavoro corrente debbano sempre avere il prefisso con il loro relativo percorso:./var=three
Peter

@ Peter.O, sì, questo è anche uno dei motivi per cui è -vstata introdotta la sintassi. Dovresti pensare alla -vsintassi come al modo preferito di svolgere compiti, andando avanti.
dubiousjim,

@ Peter.O, punto eccellente sul "gotcha" se un nome file è un'assegnazione variabile valida. Se stai usando una variabile di shell che contiene un nome file e lo passi come argomento awk, puoi usare il seguente catch:[ "$myfile" == "${myfile#/}" ] && myfile="./$myfile"
Wildcard

4

Questo è un vecchio stile di impostazione delle variabili esternamente awk. Era ambiguo (e se avessi un nome file foo=cat), quindi le versioni successive hanno aggiunto -vun'opzione. Probabilmente dovrebbe funzionare per compatibilità con le versioni precedenti, ma non puoi garantirlo. E come ho detto, l' -vopzione è più recente, quindi non tutte le versioni awkpotrebbero supportarla.


Il tuo commento sulla possibilità di uno scontro tra nomi di file è buono ... L'ho provato ed è sicuramente un problema. Ne ho scritto un po 'di più in un commento alla risposta di Mat. Grazie per aver messo in evidenza questo problema (+1)
Peter

2
In realtà, come spiegato in [Mat s answer](http://unix.stackexchange.com/a/34258/9537), -v` e l'assegnazione degli argomenti sono diversi in quando hanno effetto. Inoltre -vè in POSIX e dovrebbe essere presente in tutte le awkimplementazioni tranne quelle più antiche . Usare ./o assicurarsi che il nome del file contenga un carattere non identificativo è probabilmente il modo più affidabile per chiarire le ambiguità.
jw013
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.