Como detectar programaticamente o sabor do awk (por exemplo, gawk vs nawk)


8

Estou usando um aplicativo de linha de comando que é essencialmente uma coleção de scripts de shell bash. O aplicativo foi escrito para ser executado no BSD / OSX e também no Linux. Um dos scripts depende do awk. Ele contém dois comandos awk: um escrito para nawk (a implementação padrão do BSD awk) e outro escrito para gawk (a implementação GNU awk).

Os dois comandos do awk em questão não são compatíveis com os diferentes ambientes; em particular, o comando nawk falha quando executado com o gawk. O script verifica o nome do kernel (ou seja uname -s) para determinar o ambiente host e, em seguida, executa o comando awk apropriado. No entanto, prefiro trabalhar no Mac OS X com os principais utilitários do GNU instalados, para que o script não seja executado corretamente.

No processo de pensar sobre a melhor maneira de corrigir esse bug, ocorreu-me que seria bom saber distinguir programaticamente entre diferentes tipos de utilitários de linha de comando comuns, de preferência de maneira relativamente robusta e portátil.

Notei que o nawk não aceita o sinalizador '-V' para imprimir as informações da versão, então achei que algo como o seguinte deveria funcionar:

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

Outra variação pode ser:

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

Isso parece funcionar nos meus dois ambientes de teste (OS X e CentOS). Aqui estão as minhas perguntas:

  • Este é o melhor caminho a percorrer?
  • Existe uma maneira de estender isso para lidar com outras variações do awk (por exemplo, mawk, jawk etc.)?
  • Vale a pena se preocupar com outras versões do awk?

Também devo mencionar que sei muito pouco sobre o awk.


Se o comando awk não for extremamente complicado, ou mesmo se for, considere portá-lo para perl ou qualquer outra coisa que seja uniforme.
Wildcard

Vamos ver a versão awk por awk -Wvem vez de ambiente de acolhimento
Costas

1
Meu awk é muito fraco, mas acredito que seja bastante simples. Na verdade, eu já o reescrevi em pura festa. Mas essa é uma daquelas situações em que estou mais interessado em satisfazer minha curiosidade do que em resolver o problema original.
igal #

@Costas Algo assim realmente me ocorreu, mas eu não tinha certeza de quão frágil poderia ser; Eu sei muito pouco sobre awk. Adicionei minha solução atual à minha postagem.
igal #

1
Uma alternativa é ignorar qual versão awkestá sendo usada e, em vez disso, codificar para a especificação POSIX .
Chepner # 16/15

Respostas:


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

Alternativamente, test is awk é um link simbólico:

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

Este é bom ... mas há algumas variações (difíceis de distinguir) para as versões old-awk, nawk e as mais recentes do BWK. Para esses, um exemplo de script pode ser adaptado.
21815 Thomas

3

Tente usar o whichcomando e use seu código de saída.

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

formate seu script para usar a variável como o comando

$command '{print $1}` 

seria lido como

nawk '{print $1}`

se whichencontra nawk. Caso contrário, ele usariagawk


1
desde que commandé uma festança embutido que você pode querer usar um nome diferente para a variável, e você também pode querer ver a resposta incrivelmente detalhado sobre o porquê de muitas conchas há melhores alternativas para whicha unix.stackexchange.com/a/85250/109842
Eric Renouf

1

GNU Awk é muitas vezes instalado como gawk, com awkum link simbólico para ele em sistemas onde GNU é o padrão. Eu acho que esse é o caso dos sistemas BSD e OS X, já que eles já têm os seus awk.

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

Obrigdo por sua contribuição. Essa é uma boa ideia e você está certo de que esse é o meu caso no OS X. Mas eu esperava uma solução intrínseca, por assim dizer.
igal #

0

Um truque sujo

if nawk 'BEGIN { nawk-only-function() ;}' 
then 
   nawk -f nfile.awk ...
else 
   gawk -f gfile.awk ...
fi
  • onde nawk-only-function() existe apenas emnawk

-2

Provavelmente tentaria abusar da macro AC_PROG_AWK m4 no autoconf para escolher uma, ordenando-as de maneira apropriada. Provavelmente é um exagero


Você poderia editar para fornecer um pouco mais de detalhes sobre como você usaria essa macro para esse cenário?
Michael Homer

Na verdade, ele não diz qual foi encontrado, mas simplesmente procura implementações do awk e escolhe uma com base em seu nome.
Thomas Dickey
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.