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.