Come rilevare programmaticamente il sapore di awk (ad esempio gawk vs nawk)


8

Sto usando un'applicazione a riga di comando che è essenzialmente una raccolta di script shell bash. L'applicazione è stata scritta per essere eseguita su BSD / OSX e anche su Linux. Uno degli script si basa su awk. Contiene due comandi awk: uno scritto per nawk (l'implementazione standard di BSD awk) e uno scritto per gawk (l'implementazione di GNU awk).

I due comandi awk in questione non sono compatibili con i diversi ambienti; in particolare il comando nawk ha esito negativo quando eseguito con gawk. Lo script controlla il nome del kernel (cioè uname -s) per determinare l'ambiente host, quindi esegue il comando awk appropriato. Comunque preferisco lavorare su Mac OS X con le utility GNU core installate, quindi lo script non funziona correttamente.

Nel processo di riflessione sul modo migliore per correggere questo bug, mi è venuto in mente che sarebbe bello sapere come distinguere programmaticamente tra i diversi gusti delle comuni utility da riga di comando, preferibilmente in modo relativamente robusto e portatile.

Ho notato che nawk non accetta il flag '-V' per stampare le informazioni sulla versione, quindi ho pensato che qualcosa di simile al seguente dovrebbe funzionare:

awk -V &>/dev/null && echo gawk || echo nawk

Un'altra variante potrebbe essere:

awk -Wversion &>/dev/null && echo gawk || echo nawk

Questo sembra funzionare sui miei due ambienti di test (OS X e CentOS). Ecco le mie domande:

  • È questo il modo migliore di andare?
  • C'è un modo per estenderlo per gestire altre varianti di awk (ad esempio mawk, jawk, ecc.)?
  • Vale anche la pena preoccuparsi di altre versioni di awk?

Dovrei anche menzionare che so molto poco di Awk.


Se il comando awk non è estremamente complicato, o anche se lo è, potresti considerare di portarlo su perl o qualcos'altro che sia uniforme.
Carattere jolly

Vediamo la versione di awk awk -Wvanziché l'ambiente host
Costas,

1
Il mio awk è molto debole ma credo che sia abbastanza semplice. In realtà l'ho già riscritto in puro bash. Ma questa è una di quelle situazioni in cui sono più interessato a soddisfare la mia curiosità che a risolvere effettivamente il problema originale.
igal,

@Costas In realtà mi è successo qualcosa del genere, ma non ero sicuro di quanto potesse essere fragile; So molto poco di Awk. Ho aggiunto la mia attuale soluzione al mio post.
igal,

1
Un'alternativa è ignorare quale versione awkviene utilizzata e codificare invece la specifica POSIX .
Chepner,

Risposte:


7
if awk --version 2>&1 | grep -q "GNU Awk"
then
    awk 'BEGIN {print "I am GNU Awk"}'

elif awk -Wv 2>&1 | grep -q "mawk"
then
    awk 'BEGIN {print "I am mawk"}'

else
    awk 'BEGIN {print "I might be nawk, might not be"}'
fi

In alternativa, test is awk è un collegamento simbolico:

awk=$( command -v awk )
[[ -L $awk ]] && readlink $awk # make some decision about the result of that

Questo va bene ... ma ci sono alcune varianti (difficili da distinguere) per le versioni old-awk, nawk e BWK più recenti. Per quelli, uno script di esempio potrebbe essere personalizzato.
Thomas Dickey,

3

Prova a usare il whichcomando e usa il suo codice di uscita.

which nawk
if [[ $? == 0 ]]; then
    command="nawk"
else
    command="gawk"
fi

quindi formatta lo script per utilizzare la variabile come comando

$command '{print $1}` 

sarebbe letto come

nawk '{print $1}`

se whichtrova nawk. Altrimenti userebbegawk


1
poiché commandè un built-in bash potresti voler usare un nome diverso per la tua variabile, e potresti anche voler vedere la risposta incredibilmente dettagliata sul perché per molte shell ci sono alternative migliori whicha unix.stackexchange.com/a/85250/109842
Eric Renouf,

1

GNU Awk viene spesso installato come gawk, con awkun collegamento simbolico ad esso su sistemi in cui GNU è l'impostazione predefinita. Immagino che questo sia il caso dei sistemi BSD e OS X, dal momento che hanno già il loro awk.

if gawk '{ exit; }' < /dev/null 2> /dev/null
then
    echo "gawk available"
else
    echo "gawk not available"
fi

Grazie per il tuo contributo. Questa è una buona idea e hai ragione sul fatto che questo è il caso per me su OS X. Ma speravo in una soluzione intrinseca, per così dire.
igal,

0

Un trucco sporco

if nawk 'BEGIN { nawk-only-function() ;}' 
then 
   nawk -f nfile.awk ...
else 
   gawk -f gfile.awk ...
fi
  • dove nawk-only-function() esiste solo sunawk

-2

Probabilmente proverei ad abusare della macro m4 AC_PROG_AWK in autoconf per sceglierne una, ordinandole in modo appropriato. Tuttavia è probabilmente eccessivo


Potresti modificare per fornire un po 'più di dettaglio su come useresti quella macro per questo scenario?
Michael Homer,

In realtà non dice quale ha trovato, ma cerca semplicemente implementazioni awk e ne sceglie una in base al suo nome.
Thomas Dickey,
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.