2012-01-31 21 views
1

これは、最後の引数を追加しようとしているスクリプトで、4番目のフィールドにFNRを出力します。AWK print 0からインクリメントするFNR

#!/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 
      } 

これは、このスクリプトの出力は次のようになります。これは私の2番目のスクリプトである

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

:2番目のスクリプトに最初のスクリプトをパイピング

#!/usr/bin/awk -f 

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

は意図を返します。結果のFNRは4番目のフィールドで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から始める必要があります。

誰かが私にこれらのスクリプトを組み合わせる正しい方法を教えてもらえますか?

答えて

2

だけではなく、レコードの数よりもインクリメント変数を使用します。

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

あなたが代わりに各行のためにそれを再定義するのBEGINブロックでOFSを定義する必要があります。

{ sub(/\r$/,"") }の代わりに、まずファイルに "dos2unix"を使用しないでください。

+0

これは別のパイプです。できるだけツールの数を減らす方がいいですか?私はしばしばawkに余分な条件を入れてパイプの文字列から "grep"を残します。これは変わりません。 – ghoti

+0

@glenn jackmanありがとう、AWKを初めて聞いたのは2週間前です。変数を増やすことは、私が特定の経路に立ち往生していたために実現するにはあまりにも明白だったと思います。私はdos2unixを使ってこのスクリプトを実際に必要な唯一のステップにすることもしていません。 – jeffrbauer

1

最初のスクリプトは、/^BEGIN_DATA$/,/^END_DATA$/が満たされた場合にのみ印刷されます。

上記の条件が満たされた場合、複合スクリプトはprint sを実行し、条件が満たされているかどうかにかかわらず、すべての行に対してprint $4を実行します。

グレンジャックマンが指摘したように、問題はFNRが「レコード数」であることです。あるスクリプトから別のスクリプトにパイプすると、2番目のスクリプトは最初のスクリプトの出力のみを取得するため、各出力行は2番目のスクリプトの新しいレコードになります。

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は、未定義変数をゼロ(数値コンテキスト)または空の文字列として扱います。 –

+0

私は知っていますが、私は通常、わかりやすくするためにそれらを初期化します。 – ghoti

関連する問題