2013-02-26 79 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]並打印出由製表符分隔相應的鍵和值。

相關問題