2014-12-03 21 views
2

行計算我有一個ASCII文件結構如下:AWK - 跨越一個ASCII文件

1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,3,0,0,0,0.04,0,0,990,0 
1,0,3,0,0,0,0.12,0,0,3760,0 
1,0,3,0,0,0,0.21,0,0,5372,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
. 
. 
. 

的零點代表「隨機」數我不需要照顧。

凡塔3等於3(總是3的塊)我有 與列7和10執行一些計算:

我需要計算(0.04 * 990)+(0.12 * 3760 )+(0.21 * 5372) 並將結果插入所有三行的第5列。 第10列中的值在下一個「三個塊」中將有所不同。

以前我用awk做了很多ascii文件編輯,所以如果可能的話我也想在這裏使用它。

我的主要問題是在找到第3列= 3之後訪問接下來的兩行,然後繼續搜索兩行。


結果應該是這樣的:

1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,3,0,1618.92,0,0.04,0,0,990,0 
1,0,3,0,1618.92,0,0.12,0,0,3760,0 
1,0,3,0,1618.92,0,0.21,0,0,5372,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
1,0,4,0,0,0,0,0,0,0,0 
. 
. 
. 

我希望我能夠說明問題,如果不只是問,我會澄清!


我想:

awk -F"," '$3 == "3"' in.dat > out.dat 

,並把它與

awk -v "n=line numer" -v "s=string to insert" '(NR==n) { print s } 1' input-file 

結合,但我的主要問題是,我不知道如何來的第一行後訪問場用它來計算公式。

我真的需要使用的公式更加複雜,但我只在這裏發佈了一個簡單的示例,因爲將它適應於更復雜的解決方案沒有問題。

+3

那麼你是怎麼做的這麼遠嗎?你卡在哪裏?而且,因爲它是一個固定值,爲什麼不直接添加它,而不是每次都進行計算? – fedorqui 2014-12-03 14:02:13

+0

我試過了:awk -F「,」'$ 3 ==「3」'in.dat> out.dat並將它與awk -v「n =行數」-v「s =要插入的字符串」'( NR == n){print s} 1'輸入文件,但我的主要問題是我不知道如何訪問第一行後面的字段並將其用於計算公式中。 – MacA 2014-12-03 16:33:12

+1

我真的需要使用的公式更加複雜,但是我只在這裏發佈了一個簡單的示例,因爲將它應用於更復雜的解決方案是沒有問題的 – MacA 2014-12-03 16:38:11

回答

1

awk的getline命令爲您供應以及這裏

awk -F, -v OFS=, ' 
    $3 == 3 { 
     c = 0 
     line1 = $0; c += $7 * $10; getline 
     line2 = $0; c += $7 * $10; getline 
     line3 = $0; c += $7 * $10 
     $0 = line1; $5 = c; print 
     $0 = line2; $5 = c; print 
     $0 = line3; $5 = c 
    } 
    {print} 
' 

這還沒幹的我的口味,但它只有3行,非常可讀。

解燥

awk -F, -v OFS=, ' 
    $3 == 3 { 
     c = 0 
     for(i=1;i<=3;i++) 
     {line[i] = $0; c += $7 * $10; getline} 
     for(i=1;i<=3;i++) 
     {$0 = line[i]; $5 = c; print} 
     next 
    }1 
' 
+0

非常可讀,而且我認爲這些數據不是乾的,你只能做這麼多! ;-) – shellter 2014-12-03 16:46:29

+0

@glennjackman,我爲烘乾機解決方案添加了一個編輯,添加評論的時間太長,我也不想在自己的答案中抄襲,如果你想要的話,隨時刪除它:) – 2014-12-04 11:16:35

2

在AWK

awk -F, '$3=="3"{a[++x]=$0;y+=($7*$10)} 
     !x 
     x==3{ 
      while(++i<=x){ 
        split(a[i],b,",") 
        b[5]=y 
        for(j=1;j<length(b);j++) 
          c=j>1?c","b[j]:b[j] 
          print c 
          c=t 
      } 
      x=y=i=0 
    }' file 
  • 如果圖3是第三個字段然後保存行成陣列a和總添加到可變y
  • 打印如果x爲0
  • 如果x爲3(即第三行)將數組中的三條線分成另一個數組
  • 將第五個元素更改爲y(總數)。
  • 在另一個循環中重新創建線。
  • 打印線。

短,少耗資源的方式(信用格倫jackmans答案給我的想法)

awk -F, '$3=="3"{a[++x]=$0;y+=($7*$10)} 
     !x 
     x==3{ 
      while(++i<=x){ 
        $0=a[i] 
        $5=y 
        print 
      } 
      i=y=x=0 
    }' test 
+0

我也很喜歡你的解決方案,但我會用glenn jackman的,因爲它更容易適應我的(更復雜的)配方。 – MacA 2014-12-04 10:49:30

+0

@MacA歡呼和公平不夠:) – 2014-12-04 10:56:38