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.