如何找到像这样的awk中最小元素的索引?

时间:2013-02-26 15:34:48

标签: perl shell sed awk

输入文件

Cat|Dog|Dragon   -40|1000|-20
K|B|L|D|E        -9|1|-100|-8|9

输出文件:

Dragon 20
B      1

工作流程如下所示:在column2中,找到最小绝对值的索引,然后使用此索引获取column1中的元素。有没有人有这方面的想法?

3 个答案:

答案 0 :(得分:1)

利用我令人难以置信的感知能力,我发现这暗示这不是一个操作问题。可能是家庭作业

{
  split($1, catdog, "|")
  split($2, numbers, "|")
  smallest = -1
  for(i in numbers) {
    a = numbers[i]
    if(a < 0)
      a = -a
    if(smallest == -1 || a < smallest) {
      smallest = a
      j = i
    }
  }
  printf("%-9s %2d\n",  catdog[j], smallest)
}

答案 1 :(得分:0)

以下awk命令应该有效:

awk '
function abs(value)
{
  return (value<0?-value:value)
}
{
   len=split($2,arr,"|")
   min=abs(arr[1])
   minI=1
   for(i=1;i<=len;i++){
       if(abs(arr[i])<min){
           min=abs(arr[i])
           minI=i
       }
   }
   split($1,arr2,"|")
   print(arr2[minI],min)   
}' file

输出:

Dragon 20
B 1

答案 2 :(得分:0)

perl -lnwe '($k,$v) = map [split /\|/], split;
             my %a; 
             @a{@$k} = map abs, @$v; 
             print "$_\t$a{$_}" for 
                 (sort { $a{$a} <=> $a{$b} } keys %a)[0];
            ' input.txt

<强>输出:

Dragon  20
B       1

<强>解释

命令行切换:

    为方便起见,
  • -l处理行结尾
  • -n从参数文件名或stdin
  • 读取输入

代码:

最右边的split在空格上分割每一行。我们在管道|上再次拆分这些字段,并将结果放在数组引用[ ... ]中,以便它们适合标量变量($k$v)。然后我们声明一个词法哈希%a来保存每个新输入行的数据。我们需要这个声明来避免一行中的值泄漏到下一行。然后,我们通过哈希切片将$k中的密钥分配给$v中的绝对值。这与以下原则相同:

@foo{'a', 'b', 'c'} = (1, 2, 3);  # %foo = ( a => 1, b => 2, c => 3);

然后我们对值进行排序,使用下标[0]获取第一个值,并打印出由制表符分隔的相应键和值。