我使用以下脚本来查找我的mongodb服务器上正在运行的连接数.
mongostat | awk 'BEGIN{FS=" *"}{print "Number of connections: "$19}'
Run Code Online (Sandbox Code Playgroud)
但每10行,$ 19带有一个字符串,表示字段名称.
我想修改我的脚本只有在$19是整数时打印.
我可以尝试FS = " *[^0-9]*",但它匹配以数字开头而不是选择性打印的列.
Win*_*ute 18
使用
mongostat | awk -F ' *' '$19 ~ /^[0-9]+$/ { print "Number of connections: " $19 }'
Run Code Online (Sandbox Code Playgroud)
$19 ~ /^[0-9]+$/检查是否$19与正则表达式匹配^[0-9]+$(即,如果它只包含数字),并且只有在这种情况下才执行相关的操作.
顺便说一下,想到它,特殊的字段分隔符可能是不必要的.默认字段分隔符awk是任何空格序列,因此除非mongostat使用奇怪的制表符和空格组合,
mongostat | awk '$19 ~ /^[0-9]+$/ { print "Number of connections: " $19 }'
Run Code Online (Sandbox Code Playgroud)
应该工作正常.
检查此字段是否仅由数字组成,使其与正则表达式匹配^[0-9]+$:
$19~/^[0-9]+$/
Run Code Online (Sandbox Code Playgroud)
^代表字符串的开头和$结尾,所以我们检查它是否包含从开头到结尾的数字.随着+我们让它至少匹配一个数字,否则空场也将匹配(这样用更少的字段的文件总是匹配).
全部一起:
mongostat | awk 'BEGIN{FS=" *"} $19~/^[0-9]+$/ {print "Number of connections: "$19}'
Run Code Online (Sandbox Code Playgroud)
在这里你必须非常小心。答案并不像你想象的那么简单:
-123和+123不会在早期提议的测试中被识别为整数。sprintf. 如果浮点数表示整数,则使用格式,%d否则使用格式CONVFMT(默认%.6g)。一些更详细的解释在这篇文章的底部。因此,检查数字是否为整数或字符串是否为整数是两件不同的事情。因此,当您使用正则表达式来测试数字是否为整数时,如果您的变量仍被视为字符串(例如未处理的字段),它将完美无缺地工作。但是,如果您的变量是一个数字,awk 将在进行正则表达式测试之前首先将数字转换为字符串,因此,这可能会失败:
is_integer(x) { x ~ /^[-+]?[0-9]+$/ }
BEGIN { n=split("+0 -123 +123.0 1.0000001",a)
for(i=1;i<=n;++i) print a[i],is_integer(a[i]), is_integer(a[i]+0), a[i]+0
}
Run Code Online (Sandbox Code Playgroud)
输出:
+0 1 1 0
-123 1 1 -123
+123.0 0 1 123 << QUESTIONABLE
1.0000001 0 1 1 << FAIL
^ ^
test test
as string as number
Run Code Online (Sandbox Code Playgroud)
如您所见,最后一种情况失败了,因为 "%.6g" 转换1.0000001为字符串1,这是因为我们使用字符串操作。
验证变量是否表示整数的更通用的解决方案如下:
function is_number(x) { return x+0 == x }
function is_string(x) { return ! is_number(x) }
function is_float(x) { return x+0 == x && int(x) != x }
function is_integer(x) { return x+0 == x && int(x) == x }
BEGIN { n=split( "0 +0 -0 123 +123 -123 0.0 +0.0 -0.0 123.0 +123.0 -123.0 1.23 1.0000001 -1.23E01 123ABD STRING",a)
for(i=1;i<=n;++i) {
print a[i], is_number(a[i]), is_float(a[i]), is_integer(a[i]), \
a[i]+0, is_number(a[i]+0), is_float(a[i]+0), is_integer(a[i]+0)
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法在识别123.0为浮点数方面仍然存在问题,但那是因为 awk 只知道浮点数。
与整数值完全相等的数值(请参阅从 ISO C 标准派生的概念)应通过等效于以
sprintf字符串"%d"作为fmt参数调用函数(请参阅字符串函数)将其转换为字符串,并且被转换为第一个也是唯一一个expr参数的数值。任何其他数值都应通过等效于以sprintf变量值CONVFMT作为fmt参数调用函数并将数字值转换为第一个也是唯一的expr参数来转换为字符串。如果值为CONVFMT不是浮点格式规范。这卷 POSIX.1-2017 没有指定数字和字符串之间的显式转换。应用程序可以通过向其添加零来强制将表达式视为数字,或者可以通过将空字符串 ("")连接到它来强制将其视为字符串。来源:Awk Posix 标准