Ric*_*ian 8 awk text-processing
给定一个单列数字文件,调用它f
,下面的 awk 代码将返回最大值
cat f | awk ' BEGIN {max = -inf}
{if ($1>max) max=$1}
END { print max }
'
Run Code Online (Sandbox Code Playgroud)
获得最小值的相同方法不会产生任何结果
cat f | awk '
BEGIN {min = inf}
{if ($1<min) min=$1}
END {print min}
'
Run Code Online (Sandbox Code Playgroud)
但是,如果不是使用inf
,而是从 开始min = [some large number]
,如果数字足够大,取决于文件中的内容,则修改后的代码有效。
为什么不起作用inf
,是否有某种方法可以使min
案例像max
案例一样工作,而不必知道文件中的内容?
Adm*_*Bee 16
在实际工作最好由未初始化的最大/最小值,解决了一个假想的“最小”和“最大”号(这可能不是您所使用的框架来实现,在这种情况下awk
),但是通过使用初始化它的实际数据. 这样,它始终可以保证提供有意义的结果。
在您的情况下,您可以使用您遇到的第一个值(即第一行中的条目)分别通过添加规则来初始化max
和min
NR==1{min=$1}
Run Code Online (Sandbox Code Playgroud)
到你的awk
脚本。那么,如果第一个值已经是最小值,则后续的测试不会覆盖它,最终会产生正确的结果。这同样适用于最大值的搜索,因此在组合搜索中,您可以声明
NR==1{max=min=$1}
Run Code Online (Sandbox Code Playgroud)
至于为什么你的方法的原因inf
没有工作,用awk
而-inf
似乎,@steeldriver已经提供了你的问题,我也总结了完整起见评论一个很好的解释:
awk
,变量是“动态类型的”,即一切都可以是字符串或数字,具体取决于用途(但awk
会“记住”上次使用的内容并保留该信息以供下次操作使用)。awk
将尝试将该变量的内容解释为数字并执行运算,如果成功,则从该变量的位置将其键入为数字。inf
在没有特殊的意义awk
,因此,使用刚刚所以当,它是一个空的变量,将评估为0的运算式,例如-inf
。因此,如果您的数据都是正数,则max
初始化为变量的“最大搜索”-inf
有效,因为-inf
它只是 0(因此,最小的非负数)。min
toinf
会将变量初始化为空字符串,因为不存在算术运算可以保证将该空字符串自动转换为数字。所以在后面的对比中
NR==1{min=$1}
Run Code Online (Sandbox Code Playgroud)
输入, $1
, 与字符串值进行比较,这就是为什么也awk
将其$1
视为字符串,并执行字典比较而不是数字比较的原因。
但是,按字典顺序,没有什么比空字符串“更小”,因此min
永远不会被分配新值。因此,在该END
部分中,声明
NR==1{max=min=$1}
Run Code Online (Sandbox Code Playgroud)
打印(仍然)空字符串。
(*) 请参阅Stephen Kitt 的回答,了解带有内容的字符串"inf"
如何在awk
.
Ste*_*itt 13
您的方法不起作用,因为inf
在默认非 POSIX 模式下在 GNU AWK 中没有特殊含义。结果,它被解释为变量名,并且由于变量没有被设置为任何东西,它的值在算术上下文中为 0,在字符串上下文中为空字符串。因此,您的代码只会在为正数时找到最大值(因为max
在算术上下文中初始化),而不会找到最小值(因为min
在字符串上下文中初始化);有关详细信息,请参阅AdminBee 的回答。
要确定文件(或流)中的最小值和/或最大值,您应该遵循AdminBee's answer 中给出的建议。
但是,如果您使用的是 GNU AWK,则可以计算log(0)
以使用正无穷大或负无穷大初始化变量,并以类似于您的方法的方式使用它:
BEGIN { max = log(0) }
$1 > max { max = $1 }
END { print max }
Run Code Online (Sandbox Code Playgroud)
BEGIN { min = -log(0) }
$1 < min { min = $1 }
END { print min}
Run Code Online (Sandbox Code Playgroud)
与从第一行初始化值相比,这种方法的唯一优点是,它在没有处理任何值时提供独特的结果——正无穷大或负无穷大最终是没有看到值的可靠指标。(还有其他方法可以确定这一点,包括在从第一行初始化时检查空字符串而不是 0。)
对于处于 POSIX 模式 ( POSIXLY_CORRECT=1
) 的GNU AWK或其他符合 POSIX 的 AWK 解释器,例如mawk
,在算术上下文中"inf"
作为字符串提供会产生无穷大,这要归功于strtod
:
BEGIN { max = "-inf" + 0 }
$1 > max { max = $1 }
END { print max }
Run Code Online (Sandbox Code Playgroud)
BEGIN { min = "+inf" + 0 }
$1 < min { min = $1 }
END { print min}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1131 次 |
最近记录: |