我试图从字符串中取出两个数值,并使用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 -V
标准输入,我目前有以下内容:
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
.还有什么可能的吗?
请注意,可读性并不是真正的问题,只是长度。
答案1
由于您使用的是 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
2 8
1 9
2 10
https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html
答案2
请注意,这gensub
是一个gawk
扩展,它不能与任何其他awk
实现一起使用。另请注意,+
一元运算符不会在所有awk
实现中强制进行数字转换,使用+ 0
更可移植。
在这里你可以这样做:
tmux -V | awk -F '[ .]' '{maj = $2+0; min = $3+0; print maj, min}'
如果你不介意使用 GNUawk
扩展,你也可以这样做:
tmux -V | awk -v FPAT='[0-9]+' '{maj = $1; min = $2; print maj, min}'
答案3
您可以将版本拆分为数组:
awk '{ split($2, ver, /[.a-z]/) }'
然后使用ver[1]
代替maj
,ver[2]
代替min
。
添加a-z
到分隔符会删除版本号中的所有小写字母。 (其他解决方案在这里更好,因为它们明确地提取数字。)
答案4
另一位用户发布了这个答案,后来被删除。我认为这很有用:
使用该split()
函数,将版本字符串拆分为数组ver
,然后分别访问ver[1]
和ver[2]
而不是maj
和min
(或者简单地将值存储在这些变量中):
tmux -V | awk '{ split($2, ver, /[.a-z]/); print ver[1], ver[2] }'
这里的优点是它split()
不是gawk
扩展(尽管它的可选第四个参数seps
是)。