awk 一次分配给多个变量

vil*_*apx 11 awk gawk

我正在尝试从字符串中提取两个数值并使用awk(gawk是我专门使用的)将它们分配给变量。我想将 tmux 版本字符串中的主要和次要版本号提取到awk变量中,例如:

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

假设我的输入来自tmux -V标准输入,我目前有以下内容:

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

这是有效的,但正如 tmux 的许多用户所知,if-shell.tmux.conf文件中使用(我希望使用这些东西的地方)很容易导致配置文件中的行非常长,所以我想知道是否有办法将这两个变量结合起来分配到一个语句中以节省空间……或以任何其他方式从输入中收集这两个变量并节省空间。

我在想这样的事情:

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

...有点像在 Python 中,但在awk. 还有其他可能吗?

请注意,可读性不是真正的问题,只是长度。

gle*_*man 13

由于您使用的是 GNU awk,您可以使用 3-arg 形式match()来存储多个捕获组:

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
Run Code Online (Sandbox Code Playgroud)
2 8
1 9
2 10
Run Code Online (Sandbox Code Playgroud)

https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html


Sté*_*las 9

请注意,这gensub是一个gawk扩展,它不适用于任何其他awk实现。另请注意,+一元运算符不会在所有awk实现中强制进行数字转换,使用+ 0更便携。

在这里你可以这样做:

tmux -V | awk -F '[ .]' '{maj = $2+0; min = $3+0; print maj, min}'
Run Code Online (Sandbox Code Playgroud)

如果你不介意使用 GNUawk扩展,你也可以这样做:

tmux -V | awk -v FPAT='[0-9]+' '{maj = $1; min = $2; print maj, min}'
Run Code Online (Sandbox Code Playgroud)


Ste*_*itt 5

您可以将版本拆分为一个数组:

awk '{ split($2, ver, /[.a-z]/) }'
Run Code Online (Sandbox Code Playgroud)

然后使用ver[1]代替majver[2]代替min

添加a-z到分隔符会从版本号中删除任何小写字母。(其他解决方案在这里更好,因为它们明确地提取数字。)