awk atribui a várias variáveis ​​de uma só vez


9

Estou tentando extrair dois valores numéricos de uma string e atribuí-los a variáveis ​​usando awk( gawké o que estou usando especificamente). Eu quero puxar os números de versão principais e secundários de uma string de versão do tmux para awkvariáveis, por exemplo:

  • entrada tmux 2.8:; maj == 2emin == 8
  • entrada tmux 1.9a:; maj == 1emin == 9
  • entrada tmux 2.10:; maj == 2emin == 10

Assumindo que minha entrada vem do tmux -Vstdin, atualmente tenho o seguinte:

tmux -V | awk '{
                  maj = +gensub(/([0-9]+)\..*/, "\\1", "g", $2);
                  min = +gensub(/.*\.([0-9]+).*/, "\\1", "g", $2);
                  # ...do something with maj and min...
               }'

Isso funciona, mas como muitos usuários de tmux saber, usando if-shellno .tmux.confarquivo (onde espero usar este material) pode facilmente levar a muito longas filas no arquivo de configuração, então eu estou querendo saber se há uma maneira de combinar essas duas variáveis atribuições em uma instrução para economizar espaço ... ou qualquer outra maneira de coletar essas duas variáveis ​​da entrada e economizar espaço.

Estou pensando em algo como:

awk '{ maj, min = +gensub(/([0-9]+)\.([0-9]+).*/, "\\1 \\2", "g", $2); }'

... como em Python, mas essa sintaxe específica não existe awk. Existe mais alguma coisa possível?

Observe que a legibilidade não é realmente uma preocupação, apenas o comprimento.

Respostas:


9

Observe que gensubé uma gawkextensão, não funcionará com nenhuma outra awkimplementação. Observe também que o +operador unário não força a conversão numérica em todas as awkimplementações, o uso + 0é mais portátil.

Aqui você pode fazer:

tmux -V | awk -F '[ .]' '{maj = $2+0; min = $3+0; print maj, min}'

Se você não se importa em usar awkextensões GNU , também pode:

tmux -V | awk -v FPAT='[0-9]+' '{maj = $1; min = $2; print maj, min}'

Obrigado pelas explicações adicionais sobre compatibilidade!
21419 villapx


5

Você pode dividir a versão em uma matriz:

awk '{ split($2, ver, /[.a-z]/) }'

então use em ver[1]vez de maj, em ver[2]vez de min.

A adição a-zao separador remove qualquer letra minúscula do número da versão. (As outras soluções são melhores aqui, pois extraem números explicitamente.)


3

Outro usuário postou esta resposta e mais tarde foi excluída. Eu pensei que era útil:

Usando a split()função, divida a string da versão em uma matriz ver, acesse ver[1]e em ver[2]vez de maje min, respectivamente (ou simplesmente armazene os valores nessas variáveis):

tmux -V | awk '{ split($2, ver, /[.a-z]/); print ver[1], ver[2] }'

A vantagem aqui é que split()não é uma gawkextensão (embora seu quarto argumento opcional sepsseja).


+1, mas por que usar /[.a-z]/como o terceiro argumento (separação de campo) da splitfunção string, em vez de apenas "."?
Cbhihe

2
@ CBhihe vê a explicação na minha resposta (que eu cancelei desde que o villapx acha que é útil, graças ao villapx!).
Stephen Kitt
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.