2016-04-30 4 views
3

以前の10行が特定の列にある大きなファイルからすべての行を印刷したいとします(下の例では、列9は値<を有する。私はファイル全体をメモリに保存したくありません。私は次のように、この目的のためにAWKを使用しようとしています:以前のN行が特定の条件を満たしている大きなファイルからすべての行を印刷する

awk 'BEGIN{FS=","} 
    { 
    for (i=FNR,i<FNR+10, i++) saved[++s] = $0 ; next 
    for (i=1,i<s, i++) 
     if ($9<1) 
    print saved[s]; delete saved; s=0 
    }' file.csv 

このコマンドの目標は10の前の行を保存することです、そして、これらの行の各列9は私の基準を満たしていることを確認することは、その後の印刷します現在の行。これに関する助け、またはこれを行うためのより効率的な方法に関する提案は、非常に感謝しています!ここで

+0

カンマの代わりに**セミコロン**を使用して 'for(..; ..; ..)'を使用してください。 –

答えて

1

はGNU Awkのためのソリューションです:awk -f chk_prev_lines.awk your_file

BEGIN { FS="," 
     CMP_LINE_NR=10 
     CMP_VAL = 1  } 

FNR > CMP_LINE_NR { 
     ok = 1 
     # check the stored values 
     for(i = 0; i< CMP_LINE_NR; i++) { 
      if (!(prev_Field9[ i ] < CMP_VAL)) { 
      ok = 0 
      break # early return 
      } 
     } 
     if(ok) print 
     } 

     { # store $9 for the comparison 
     prev_Field9[ FNR % CMP_LINE_NR] = $9 
     } 

chk_prev_lines.awkはこのようにそれを使用してください。説明

  • CMP_LINE_NR

    は、前の行からの多くの値は、

  • CMP_VAL比較
  • FNR > CMP_LINE_NRが世話を条件に使用される値を決定
  • に格納されている方法を決定し、その前の最初の行、すなわち行がチェックされている場合は、CMP_LINE_NR +1のものです。これは、これまでの多くの行の最初のものです。
  • 最後のアクションは値$9を保存します。このアクションはすべての行に対して実行されます。
+0

awkで大文字の変数名を使用しないでください。変数名は組み込みの変数名のように見え、組み込みの変数名と衝突する可能性があります。また、これは単なるスタイルかもしれませんが、単語は 'prev_field9'のアンダースコアや' prevField9'の変更で区切られるように変数名が付けられていますが、 'prev_Field9'のように両方を行うと奇妙に見えますあなたが変数を初期化する必要がないので、awkの特別な問題であるコードを後で強化する場合に使用するのを忘れないようにするのは難しいでしょう。 –

2

メモリに何かを保存したり、値を明示的にループする必要はありません。

awk -F, '(c=($9<1?c+1:0))>9' file 
もちろんの未テスト

あなたが任意のサンプル入力または予想される出力を提供していませんでしたので、とても数学を確認するが、こと:最後の10行(包括的)が$ 9値< 1だけである持っていた場合、現在の行を印刷するには正しいアプローチであり、数学が間違っている場合は、>9>10または必要なものに変更するだけです。

関連する問題