web-dev-qa-db-fra.com

Awk Attribuer à plusieurs variables à la fois

J'essaie de tirer deux valeurs numériques d'une chaîne et de les assigner à des variables en utilisant awk (gawk est ce que j'utilise spécifiquement). Je veux tirer les numéros de version majeurs et mineurs d'une chaîne de version TMUX en awk variables, par exemple:

  • saisir: tmux 2.8; maj == 2 et min == 8
  • saisir: tmux 1.9a; maj == 1 et min == 9
  • saisir: tmux 2.10; maj == 2 et min == 10

En supposant que mon entrée provienne de tmux -V sur stdin, j'ai actuellement ce qui suit:

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

Cela fonctionne, mais autant de nombreux utilisateurs de TMUX savent, en utilisant if-Shell dans le .tmux.conf fichier (où j'espère utiliser ce matériel) peut facilement conduire à vraiment lignes longues dans le fichier de configuration, donc je me demande s'il y a un moyen de combiner ces deux missions variables en une seule déclaration à Enregistrer l'espace ... ou tout autre moyen de glaner ces deux variables à partir de l'entrée et de la sauvegarde de l'espace.

Je pense à quelque chose comme:

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

... genre de comme dans Python, mais cette syntaxe particulière n'existe pas dans awk. Y a-t-il autre chose qui est possible?

Notez que la lisibilité n'est pas vraiment une préoccupation, juste la longueur.

10
villapx

Notez que gensub est une extension gawk, elle ne fonctionnera pas avec une autre mise en œuvre awk. Notez également que le + Opérateur unaire ne force pas la conversion numérique dans toutes les implémentations awk, en utilisant + 0 est plus portable.

Ici vous pourriez faire:

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

Si cela ne vous dérange pas d'utiliser GNU awk extensions, vous pouvez également faire:

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

Puisque vous utilisez GNU AWK, vous pouvez utiliser la forme 3-AG de match() pour stocker plusieurs groupes de capture:

awk '
    match($0, /([0-9]+)\.([0-9]+)/, m) {maj=m[1]; min=m[2]; print maj, min}
' <<END
tmux 2.8
tmux 1.9a
tmux 2.10
END
2 8
1 9
2 10

https://www.gnu.org/software/gawk/manual/html_node/string-fonctions.html

13
glenn jackman