2012-01-31 89 views
1

這是我試圖添加最後一個參數的腳本,將FNR打印到第四個字段中。AWK打印FNR從0開始遞增

#!/usr/bin/awk -f 

{ sub(/\r$/,"") } 

/^BEGIN_DATA_FORMAT/{ 
     getline 
      for (i=1;i<=NF;i++) 
        if ($i~/LAB/) a[i]=$i 
       } 


/^BEGIN_DATA$/,/^END_DATA$/{ 
      s=""; 
      if (NF<2) next; else 
       for (j in a) 
      s=s?s"\t"$j:$j 
      print s 
      } 

這是該腳本輸出的樣子:

48.34 -55.88 19.19 
26.95 24.36 13.43 
25.53 4.45 -20.68 
71.27 6.68 24.28 
... 

這是我的第二個腳本:

#!/usr/bin/awk -f 

{ OFS = "\t"; $4="(Untitled "FNR-1")"; print $0 } 

管道中的第一個腳本進入第二腳本返回預期結果與FNR從第四個字段中的0開始。

48.34 -55.88 19.19 (Untitled 0) 
26.95 24.36 13.43 (Untitled 1) 
25.53 4.45 -20.68 (Untitled 2) 
71.27 6.68 24.28 (Untitled 3) 
... 

我試過組合腳本,但我沒有得到我想要的輸出。

#!/usr/bin/awk -f 

{ sub(/\r$/,"") } 

/^BEGIN_DATA_FORMAT/{ 
     getline 
      for (i=1;i<=NF;i++) 
        if ($i~/LAB/) a[i]=$i 
       } 


/^BEGIN_DATA$/,/^END_DATA$/{ 
      s=""; 
      if (NF<2) next; else 
       for (j in a) 
      s=s?s"\t"$j:$j 
      print s 
         } 

    { 
     OFS = "\t" 
     $4="(Untitled "FNR-1")" 
     print $4 
    } 

這是給出的輸出。問題是它引用的是相同的文件,而不是最後一個命令的輸出。

(Untitled 0) 
(Untitled 1) 
(Untitled 2) 
(Untitled 3) 
(Untitled 4) 
(Untitled 5) 
(Untitled 6) 
(Untitled 7) 
(Untitled 8) 
(Untitled 9) 
(Untitled 10) 
(Untitled 11) 
(Untitled 13) 
(Untitled 14) 
(Untitled 15) 
48.34 -55.88 19.19 
(Untitled 17) 
26.95 24.36 13.43 
(Untitled 18) 
25.53 4.45 -20.68 
(Untitled 19) 
71.27 6.68 24.28 
(Untitled 20) 
... 

我也試過這樣:

#!/usr/bin/awk -f 

{ sub(/\r$/,"") } 

/^BEGIN_DATA_FORMAT/{ 
     getline 
      for (i=1;i<=NF;i++) 
        if ($i~/LAB/) a[i]=$i 
       } 


/^BEGIN_DATA$/,/^END_DATA$/{ 
      s=""; 
      if (NF<2) next; else 
       for (j in a) 
      s=s?s"\t"$j:$j 

     OFS = "\t" 
     $4="(Untitled "FNR-1")" 
     print s OFS $4 
      } 

輸出更接近,但問題是,它仍然是爭論的FNR計數。我需要它爲0

48.34 -55.88 19.19 (Untitled 17) 
26.95 24.36 13.43 (Untitled 18) 
25.53 4.45 -20.68 (Untitled 19) 
71.27 6.68 24.28 (Untitled 20) 
... 

開始有人能告訴我正確的方法對這些腳本結合?

回答

2

只需使用一個遞增的變量,而不是備案號:

print s, "(Untitled " count++ ")" 

你應該在BEGIN塊定義,而不是將其重新定義爲每一行OFS

而不是在做{ sub(/\r$/,"") }爲什麼不先在文件上使用「dos2unix」?

+0

這是另一個管道。如果可以,最好減少工具的數量,不是嗎?我通常會在awk中添加一個額外的條件,從而在一串管道中留下「grep」。這也不例外。 – ghoti 2012-02-01 02:54:03

+0

@glenn jackman謝謝,我有史以來第一次聽說AWK。我認爲增加一個變量太清楚了,因爲我被困在一個特定的路徑上。我也沒有使用dos2unix來運行這個腳本真的是唯一需要的步驟。 – jeffrbauer 2012-02-01 03:08:22

1

只有當/^BEGIN_DATA$/,/^END_DATA$/符合時,纔會打印您的第一個腳本。

當滿足上述條件時,您的組合腳本執行它的print s,並且對於每一行都執行print $4,無論條件是否滿足。

正如glenn jackman指出的那樣,問題在於FNR是「記錄數量」。當您從一個腳本傳輸到另一個腳本時,第二個腳本只會獲得第一個腳本的輸出,因此每個輸出行都是第二個腳本的新記錄。

您需要與FNR不同的計數器。

BEGIN { 
    count=0; 
} 

... 

/^BEGIN_DATA$/,/^END_DATA$/ { 
    s=""; 
    if (NF<2) { 
    next; 
    } else { 
    for (j in a) [ 
      s=s?s"\t"$j:$j; 
    } 
    printf("%s\t(Untitled %d)", s, count++); 
    } 
} 
+1

初始化變量不是必須的:awk會將未定義的變量視爲零(在數字上下文中)或空字符串。 – 2012-02-01 11:47:57

+0

我知道,但爲了清晰起見,我通常會初始化它們。 – ghoti 2012-02-01 13:23:58