awk aynı anda birden çok değişkene ata


9

Bir dize dışında iki sayısal değerleri çekmek ve bunları kullanarak değişkenleri atamak çalışıyorum awk( gawközellikle ne kullanıyorum). awkDeğişkenlere bir tmux sürüm dizesi dışında büyük ve küçük sürüm numaralarını çekmek istiyorum , örneğin:

  • girdi tmux 2.8:; maj == 2vemin == 8
  • girdi tmux 1.9a:; maj == 1vemin == 9
  • girdi tmux 2.10:; maj == 2vemin == 10

Girişimin tmux -Vstdin'den geldiğini varsayarsak , şu anda aşağıdakilere sahibim:

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

Bu çalışır, ancak kullanarak tmux know birçok kullanıcı olarak if-shelliçinde .tmux.confrahatlıkla yol açabilir (Bu tür şeyleri kullanmak için umut) dosyası gerçekten bu iki değişkeni birleştirmek için bir yol var olmadığını merak ediyorum bu yüzden, yapılandırma dosyasında uzun hatlar yerden tasarruf etmek için bir ifadeye atama ... ya da bu iki değişkeni girişten ayırıp yerden tasarruf etmenin başka bir yolu.

Şöyle bir şey düşünüyorum:

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

... Python'da olduğu gibi, ancak söz konusu sözdizimi mevcut değil awk. Mümkün olan başka bir şey var mı?

Okunabilirliğin gerçekten bir endişe olmadığını, sadece uzunluğa dikkat edin.

Yanıtlar:


9

Bunun gensubbir gawkuzantı olduğunu, başka bir awkuygulamayla çalışmadığını unutmayın . Ayrıca, +tekli operatörün tüm awkuygulamalarda sayısal dönüşümü zorlamadığını , + 0kullanımının daha taşınabilir olduğunu unutmayın.

Burada şunları yapabilirsiniz:

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

GNU awkuzantılarını kullanmanın bir sakıncası yoksa şunları da yapabilirsiniz:

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

Uyumlulukla ilgili ek açıklamalar için teşekkürler!
villapx


5

Sürümü bir diziye bölebilirsiniz:

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

Daha sonra kullanmak ver[1]yerine maj, ver[2]yerine min.

a-zAyırıcı eklemek , sürüm numarasından tüm küçük harfleri kaldırır. (Diğer çözümler burada açıkça sayılar çıkardıkları için daha iyidir.)


3

Başka bir kullanıcı bu yanıtı gönderdi ve daha sonra silindi. Yararlı olduğunu düşündüm:

split()İşlevi kullanarak, sürüm dizesini bir diziye ayırın ve sırasıyla sırasıyla ve yerine vererişin (veya değerleri bu değişkenlerde depolayın):ver[1]ver[2]majmin

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

Burada artı split()bir gawkuzantı değil (isteğe bağlı dördüncü argümanı olsa da seps).


+1 ama neden sadece yerine string fonksiyonunun /[.a-z]/üçüncü (alan ayırma) argümanı olarak splitkullanılsın "."?
Cbhihe

2
@Chhihe cevabımın açıklamasına bakın (villapx'in yararlı olduğunu düşündüğü için silindim, teşekkürler villapx!).
Stephen Kitt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.