Existem 2 maneiras de definir os vars do awk via linha de comando?


10

Notei um awkexemplo de O'Reilly (1997) que atribuiu uma variável awk, definindo-a na linha de comando após o texto do programa. Funciona, mas não consigo encontrar essa sintaxe no man / info awk . Acabei de sentir falta disso; é privado ...? A única sintaxe que eu vi no manual é a -vopção.

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

Resultado: cat dog

Respostas:


11

Na verdade, está no POSIX awk(link para o POSIX 2008, versões anteriores também o consideravam). -vé descrito na seção Opções , o contrário é na seção Operandos .

Há uma diferença entre -ve passar as atribuições no final com os nomes dos arquivos:

  • Com -v:

O aplicativo deve garantir que o argumento de atribuição esteja na mesma forma que um operando de atribuição. A atribuição de variável especificada deve ocorrer antes da execução do programa awk, incluindo as ações associadas aos padrões BEGIN (se houver). Várias ocorrências dessa opção podem ser especificadas.

  • Misturado com os nomes dos arquivos:

[...] Cada atribuição de variável deve ocorrer imediatamente antes do processamento do seguinte arquivo , se houver. Assim, uma atribuição antes do argumento do primeiro arquivo deve ser executada após as ações BEGIN (se houver), enquanto uma atribuição após o último argumento do arquivo deve ocorrer antes das ações END (se houver). Se não houver argumentos de arquivo, as atribuições devem ser executadas antes do processamento da entrada padrão.

Exemplo:

$ 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

Uau! Isso adiciona alguns pontos de controle interessantes ... certamente será útil. Obrigado ...
Peter.O

1
Meu inicial "Uau!" ainda é válido, mas foi atenuado um pouco ao analisar mais profundamente a resposta do Arcege ... Testei-o com um arquivo real chamado "var = three" ... awkdeu precedência ao fato de ser uma atribuição de variável ... Isso tem um corolário importante , ie. Em todos os casos, quando um nome de arquivo tiver esse formato, ele será ignorado e a variável será definida ... Parece que a única maneira de evitar esse conflito é garantir que os nomes de arquivo para o diretório de trabalho atual sempre sejam prefixados com o seu caminho relativo:./var=three
Peter.O

@ Peter.O, sim, também é uma das razões pelas quais a -vsintaxe foi introduzida. Você deve pensar na -vsintaxe como a maneira preferida de realizar tarefas, daqui para frente.
precisa

@ Peter.O, excelente argumento sobre a "pegadinha" se um nome de arquivo é uma atribuição de variável válida. Se você estiver usando uma variável de shell que contém um nome de arquivo e passá-lo como argumento awk, poderá usar a seguinte captura:[ "$myfile" == "${myfile#/}" ] && myfile="./$myfile"
Curinga

4

Este é um estilo antigo de definir variáveis ​​externamente em awk. Como era ambíguo (e se você tivesse um nome de arquivo foo=cat), as versões posteriores adicionaram uma -vopção. Provavelmente deve funcionar para compatibilidade com versões anteriores, mas você não pode garantir. E como eu disse, a -vopção é mais nova, portanto nem todas as versões awkpodem suportá-la.


Seu comentário sobre a possibilidade de um conflito de nome de arquivo é bom ... Eu testei e é definitivamente um problema. Eu escrevi um pouco mais sobre ele em um comentário para a resposta de Mat .. Thansk para destacar esta questão (+1)
Peter.O

2
Na verdade, conforme explicado em [Mat- s answer](http://unix.stackexchange.com/a/34258/9537), v` e atribuição de argumentos, são diferentes quando entram em vigor. Também -vestá no POSIX e deve estar presente em todas as awkimplementações, exceto as mais antigas . Usar ./ou garantir que o nome do arquivo contenha um caractere não identificador é provavelmente a maneira mais confiável de desambiguar.
jw013
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.