awk призначити декілька змінних одночасно


9

Я намагаюся витягнути два числових значення з рядка і призначити їх змінним за допомогою awk( gawkсаме це я використовую конкретно). Я хочу витягнути основні та другорядні номери версій із рядка версії tmux у awkзмінні, наприклад:

  • вхід tmux 2.8:; maj == 2іmin == 8
  • вхід tmux 1.9a:; maj == 1іmin == 9
  • вхід tmux 2.10:; maj == 2іmin == 10

Якщо припустити, що мій внесок походить від tmux -Vstdin, у мене зараз є такі:

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

Це працює, але , як багато користувачів tmux знають, використовуючи if-shellв .tmux.confфайлі (де я сподіваюся використовувати цей матеріал) може легко призвести до дуже довгих рядків у файлі конфігурації, так що мені цікаво , якщо є спосіб об'єднати ці дві змінні призначення в одному операторі, щоб заощадити простір ... або будь-який інший спосіб отримати ці дві змінні з вхідних даних та заощадити простір.

Я думаю про щось на кшталт:

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

... як у Python, але цього синтаксису не існує в awk. Чи є ще щось, що можливо?

Зауважте, що читабельність насправді не є проблемою, а лише довжиною.

Відповіді:


9

Зауважте, що gensubце gawkрозширення, воно не працюватиме з будь-якою іншою awkреалізацією. Також зауважте, що +одинарний оператор не примушує числових перетворень у всіх awkреалізаціях, а використання + 0є більш портативним.

Тут ви можете зробити:

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

Якщо ви не проти використовувати awkрозширення GNU , ви також можете зробити:

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

Дякуємо за додаткові пояснення щодо сумісності!
villapx


5

Ви можете розділити версію на масив:

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

потім використовуйте ver[1]замість maj, ver[2]а не min.

Додавання a-zв роздільник видаляє будь-яку малу літеру з номера версії. (Інші рішення тут краще, оскільки вони явно витягують числа.)


3

Інший користувач опублікував цю відповідь, і вона пізніше була видалена. Я вважав, що це корисно:

Використовуючи split()функцію, розділити рядок версії в масив ver, то доступ , ver[1]і ver[2]замість того , majі min, відповідно (або просто зберігати значення в цих змінних):

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

Плюс у тому, що split()це не gawkрозширення (хоча його необов'язковий четвертий аргумент seps).


+1, але навіщо використовувати /[.a-z]/як третій (розділення поля) аргумент splitрядкової функції, а не просто "."?
Cbhihe

2
@Cbhihe дивіться пояснення у моїй відповіді (яку я відмітив, оскільки villapx вважає, що це корисно, дякую villapx!).
Стівен Кітт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.