使用 awk 自定义函数打印文件中的最小整数?

使用 awk 自定义函数打印文件中的最小整数?

awk函数在文件名中看起来像这样fun.awk

{
print small()
}
function small()

{
a[NR]=$0

smal=0

for(i=1;i<=3;i++)
{
if( a[i]<a[i+1])

smal=a[i]

else

smal=a[i+1]

}
return smal
}

内容awk.write

1
23 
32

命令awk是:

awk -f fun.awk awk.write

它没有给我任何结果?为什么?

更新

{

print f()
}
function f()

{


if(NR==1){s=$0}


if($0<p)

{s=$0}

{p=$0}

 { return s}

}

答案1

代码的两个版本都将small在输入文件的每一行上运行该函数。如果您想找到整个文件中的最小数字,则只需在整个文件处理完毕后在最后运行该函数一次。您更新后的函数看起来可以正常工作并打印正确的输出三次,但这只是因为最小的数字位于第一行。如果您在此文件上运行它:

$ cat awk.write
10
9
8

您将得到以下输出:

awk -f fun.awk awk.write
10
9
8

这是因为每次运行该函数时,当前行号都小于已保存的行号,因此会打印出来。您需要使用一个END{}块并在那里运行该函数:

function small(){
    for(i=1;i<=NR;i++)
    {
      ## If smal is not set or if it is greater than a[i]
      if(smal=="" || a[i]<=smal)
        smal=a[i]
    }
return smal
}
{
    ## NR is the current line number. This saves the current line
    ## in the array a.
    a[NR]=$0
}
## This will be executed only after everything has been read
END{
    print small()
}

我还概括为使用NR而不是3这样它可以在任意数量的行上工作。您可以进一步简化为:

{
    if(small=="" || $0<small){
    small=$0
    }
}
END{print small}

这与这一行相同:

awk '(small=="" || $0<small){small=$0}END{print small}' awk.write   

答案2

if 子句中的语法错误,请使用:

if( a[i]<a[i+1]){
  smal=a[i]
}else{
  smal=a[i+1]
}

但是,它会打印每一行的值。


对于您的问题,更好的解决方案是:

sort -n file | head -1
  • 这会将文件内容按数字升序排序,并head仅打印第一行。

或者如果必须是awk

awk 'NR==1{s=$0} $0<p{s=$0} {p=$0} END{print s}' file
  • NR==1{s=$0}如果是第一行,则设置s变量。
  • $0<p{s=$0}如果当前行小于前一行,则将s变量设置为该值。
  • {p=$0}对于每一行,p为下一次迭代设置(上一个)变量。
  • END{print s}当处理完所有行后,打印 的值s

编辑:所有这些都在一个函数中,看起来是:

awk 'function f(){ if(NR==1){s=$0} if($0<p){s=$0}p=$0} {f()} END{print s}' file

相关内容