AWK 从数组中提取长度较短的字符串

AWK extract the shorter string in length from an array

我有一个数组,其中包含 "gummy"、"owl"、"table" 等单词……我需要的是提取长度较短的单词并将其分配给一个变量。

我试过的

st[] = x;
for (i in st)
{
    if(min < st[i])
    {
        min = st[i];
    }
}
ld=min;

所以为了找到最短的长度,请考虑这个:

$ ./bar.awk
shortest= -1   i= 1    st[i]= gummy
first time, now shortest= 5
shortest= 5   i= 2    st[i]= owl
found shorter value, now shortest= 3
shortest= 3   i= 3    st[i]= table
shortest= 3   i= 4    st[i]= cat
done. shortest= 3

$ cat bar.awk
#!/usr/bin/awk -f

BEGIN {
   st[1]="gummy"
   st[2]="owl"
   st[3]="table"
   st[4]="cat"

   shortest = -1
   for (i in st)
   {
       print "shortest=", shortest, "  i=", i, "   st[i]=", st[i]
       if( shortest == -1 ) {
          shortest = length( st[i] )
          print "first time, now shortest=", shortest
       } else if( length( st[i] ) < shortest ) {
          shortest = length( st[i] )
          print "found shorter value, now shortest=", shortest
       }
   }
   print "done. shortest=", shortest
}

原文post: 这是一个简短的示例,它应该可以帮助您入门。

我想把打印东西的使用调出来看看代码是干什么的。如果您不确定为什么某些东西以特定方式工作,请在它周围添加印刷品以显示所涉及的值,直到您理解为止。打印不需要花哨或任何东西,只要足以让您了解不同的表达式在做什么给定变量在任何时间点恰好是什么。

注 1:我们从 candidate 作为数组中的一个元素开始。这有点多余,因为循环会进行不必要的比较,但这样写很容易,清楚发生了什么,我们避免了可能的错误(如果你初始化 candidate = "" 并且你的数组没有有空字符串值吗?)

注 2:我将 st[i] 分配给一个变量 'value' 因为我认为这样更清楚地表明 st[i] 无处不在(任何一种方式都可以)。

$ chmod +x foo.awk
$ cat foo.awk
#!/usr/bin/awk -f

BEGIN {
   st[1]="gummy"
   st[2]="owl"
   st[3]="table"
   st[4]="cat"

   candidate=st[1]
   for (i in st)
   {
       print "candidate=", candidate
       print "        i=", i
       print "    st[i]=", st[i]
       value = st[i]
       if( length( value ) < length(candidate) )
       {
           candidate = value
           print "found shorter value, changing candidate=", candidate
       }
   }
   print "done. candidate=", candidate
}

$ ./foo.awk 
candidate= gummy
        i= 1
    st[i]= gummy
candidate= gummy
        i= 2
    st[i]= owl
found shorter value, changing candidate= owl
candidate= owl
        i= 3
    st[i]= table
candidate= owl
        i= 4
    st[i]= cat
done. candidate= owl

问题:假设您有两个(或更多)候选人,他们都同样矮,如上例中的 "cat" 和 "owl"。您想产生哪些价值?你能想出一种方法来产生所有最短的值吗?

我想你只是忘了调用 length 函数:

awk '
BEGIN {
  st[1] = "gummy"
  st[2] = "owl"
  st[3] = "table"

  for (i in st)
  {
    if (min == "" || length (st[i]) < length (min))
    {
      min = st[i]
    }
  }

  print min

}
'

结果:

owl

此脚本已使用多个 awk(包括 GNU awk 和 mawk)进行测试,将所需功能抽象为 awk 函数。

# For each input line, this script splits the line into tokens
# in the usual (awkish) way and emits a token with minimal
# length if there are any, or otherwise the empty string.

awk '
  function minimalist(a, ix,min,n) {
    n=length(a);
    if (n==0) { return "";}
    ix=1; min=length(a[ix]); 
    for (i=2; i<=n; i++) {
      if (length(a[i]) < min) {
        ix=i; min=length(a[ix]);
      }
    }
    return a[ix];
  }

  { n=split([=10=], a);
    answer = minimalist(a);
    print answer;
  }'

bash build-ins 的替代解决方案。

$ a=(gummy owl table) 
$ for i in ${a[@]}; do echo ${#i} $i; done | sort -n | head -1 | cut -d' ' -f2

owl
$ cat tst.awk
BEGIN {
    array["gummy"]
    array["owl"]
    array["table"]

    for (word in array) {
        cur = length(word)
        if ( (min == 0) || (cur < min) ) {
            shortest = word
            min = cur
        }
    }

    print shortest
}

$ awk -f tst.awk
owl