2013-02-26 82 views
0

输入文件如何在awk中找到最小元素的索引?

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

输出文件:

Dragon 20 
B  1 

工作流程是这样的:在列2中,找到最小绝对值的索引,然后使用此索引在列1取元件。有没有人有关于此的想法?

+0

想法是,取第二列,用'|'分隔,找到最小的abs,得到索引,拆分第一列,取值,打印。转到下一行,直到文件结束。 – Kent 2013-02-26 15:48:57

+0

@Kent刚工作过一整夜..我会关闭这个.. – 2013-02-26 16:07:01

回答

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 
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) 
} 
+0

我对你的评论笑了很多 – fedorqui 2013-02-26 16:25:05

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读取从参数文件名输入或标准输入

的代码:

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

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

然后我们排序的值的哈希,采取的第一个值与标[0]并打印出由制表符分隔相应的键和值。

相关问题