2015-12-28 51 views
-1

我有一个包含“gummy”,“owl”,“table”等单词的数组...我需要的是提取长度较短的单词并将其分配给变量。AWK从数组中提取长度较短的字符串

我已经试过

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

其中是数组?它是一个bash数组还是一个awk数组?请提供[mcve] – fedorqui

+0

@fedorqui您是否阅读过该问题的标题?,您是否阅读过标签? – JCG

+1

根据“不清楚你在问什么”的票数,我不是唯一这样认为的人。 – fedorqui

回答

1

所以对于刚刚发现了最短的长度,可以这样考虑:

$ ./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 
} 

原帖: 这里有一个简单的例子,它应该让你开始。

我想调用打印的东西来看看代码在做什么。如果您不确定某个特定方式的工作原理,请在其周围添加打印以显示所涉及的值,直到您理解为止。打印不需要花哨或任何东西,仅仅足以让你理解不同的表达式在做什么,在给定的变量发生在任何时间点。

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

注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 

问题:假设你有两个(或多个)候选都同样短,就像上面的例子中“猫”和“猫头鹰”。你想生产哪个价值?你能想出一种产生所有最短值的方法吗?

+0

该数组不包含空值,只是我需要得到长度较短的单词,而不管该长度是否重复。我只需要使用字长度在以后在substr()函数中使用 – JCG

+0

这很酷,我明白从来没有“”(空)值。这个例子有意义吗?它应该适合你正在做的事情。既然你只是在最短的LENGTH之后,我们可以做得更好......我会相应地编辑答案。 – jgreve

0

我想你忘记调用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 
1

这个脚本,它已经与数个awks(包括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($0, a); 
    answer = minimalist(a); 
    print answer; 
    }' 
1

用bash构建插件的替代解决方案。

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

owl 
1
$ 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 
相关问题