awk si assegna a più variabili contemporaneamente


9

Sto cercando di estrarre due valori numerici da una stringa e assegnarli alle variabili usando awk( gawkè quello che sto usando specificamente). Voglio estrarre i numeri di versione maggiore e minore da una stringa di versione tmux in awkvariabili, ad esempio:

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

Supponendo che il mio input provenga da tmux -Vstdin, al momento ho il seguente:

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

Funziona, ma come molti utenti di tmux sanno, usare if-shellnel .tmux.conffile (dove spero di usare questa roba) può facilmente portare a righe molto lunghe nel file di configurazione, quindi mi chiedo se c'è un modo per combinare queste due variabili assegnazioni in un'istruzione per risparmiare spazio ... o in qualsiasi altro modo per raccogliere queste due variabili dall'input e risparmiare spazio.

Sto pensando a qualcosa del tipo:

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

... un po 'come in Python, ma quella particolare sintassi non esiste awk. C'è qualcos'altro che è possibile?

Nota che la leggibilità non è davvero un problema, ma solo la lunghezza.

Risposte:


9

Nota che gensubè gawkun'estensione, non funzionerà con nessun'altra awkimplementazione. Si noti inoltre che l' +operatore unario non impone la conversione numerica in tutte le awkimplementazioni, l'utilizzo + 0è più portabile.

Qui puoi fare:

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

Se non ti dispiace usare le awkestensioni GNU , puoi anche fare:

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

Grazie per le spiegazioni aggiuntive sulla compatibilità!
villapx


5

Puoi dividere la versione in un array:

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

quindi utilizzare ver[1]invece di maj, ver[2]anziché min.

L'aggiunta a-zal separatore rimuove qualsiasi lettera minuscola dal numero di versione. (Le altre soluzioni sono migliori qui poiché estraggono esplicitamente i numeri.)


3

Un altro utente ha pubblicato questa risposta, che è stata successivamente eliminata. Ho pensato che fosse utile:

Utilizzando la split()funzione, dividere la stringa di versione in un array ver, quindi accedere ver[1]e ver[2]anziché e maje min, rispettivamente (o semplicemente archiviare i valori in tali variabili):

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

Il vantaggio qui è che split()non è gawkun'estensione (anche se il suo quarto argomento opzionale sepsè).


+1 ma perché usare /[.a-z]/come terzo argomento (separazione dei campi) della splitfunzione stringa, anziché solo "."?
Cbhihe,

2
@Cbhihe vedi la spiegazione sulla mia risposta (che ho cancellato dal momento che villapx pensa che sia utile, grazie villapx!).
Stephen Kitt,
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.