2016-04-30 6 views
3

Ich möchte jede Zeile aus einer großen Datei, wo die vorherigen 10 Zeilen einen bestimmten Wert in einer bestimmten Spalte haben, drucken (im Beispiel unten, Spalte 9 hat einen Wert < 1). Ich möchte nicht die gesamte Datei im Speicher ablegen. Ich versuche, awk zu diesem Zweck wie folgt zu verwenden:Drucken Sie jede Zeile aus einer großen Datei, wo die vorherigen N Zeilen bestimmte Kriterien erfüllen

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 

Das Ziel dieses Befehls die 10 vorhergehenden Zeilen zu speichern ist, dass dann überprüfen Sie die Spalte 9 in jeder dieser Zeilen meine Kriterien erfüllt, dann wird der Druck aktuelle Zeile. Jede Hilfe mit diesem oder Vorschlag auf eine effizientere Weise, dies zu tun, wird sehr geschätzt!

+0

Verwenden Sie 'für (..; ..; ..)' mit ** Semikolons ** anstelle von Kommas. –

Antwort

1

Hier ist eine Lösung für GNU Awk:

chk_prev_lines.awk

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 
     } 

es wie folgt verwendet: awk -f chk_prev_lines.awk your_file.

Erläuterung

  • CMP_LINE_NR bestimmt, wie viele Werte von vorherigen Zeilen gespeichert sind
  • CMP_VAL die Werte bestimmt, für den Vergleich verwendet
  • Die Bedingung FNR > CMP_LINE_NR Sorgfalt auf, dass die erste Zeile, der zuvor Zeilen geprüft werden, ist die mit CMP_LINE_NR +1. Es ist das erste mit so vielen vorherigen Zeilen.
  • Die letzte Aktion speichert den Wert $9. Diese Aktion wird für alle Zeilen ausgeführt.
+0

Verwenden Sie nicht alle Großbuchstaben-Variablennamen in awk, da sie wie eingebaute Variablennamen aussehen und die Möglichkeit eines Konflikts mit einem eingebauten Variablennamen schaffen. Dies mag auch nur eine Stilsache sein, aber es ist üblich, dass Variablen so benannt werden, dass Wörter durch den Unterstrich 'prev_field9' oder durch eine Änderung des Falls' prevField9' getrennt sind, aber beides wie in 'prev_Field9' erscheint seltsam und I THINK würde schwer für die Leute zu erinnern, zu verwenden, wenn/wenn der Code später zu verbessern, was ein besonderes Problem für awk ist, da Sie keine Variablen initiieren müssen, so dass eine Fehlbuchstabierung nur eine neue erstellt. –

2

Keine Notwendigkeit, etwas im Speicher zu speichern oder explizite Schleifen auf Werte. Um die aktuelle Zeile gedruckt werden, wenn die letzten 10 Zeilen (einschließlich) ist nur einen $ 9 Wert < 1 haben:

awk -F, '(c=($9<1?c+1:0))>9' file 

Ungeprüfte natürlich, da Sie keinen Abtastwerteingang vorsah oder erwartete Ausgabe überprüfen, so dass die Mathematik, sondern dass ist der richtige Ansatz und wenn die Mathematik falsch ist, dann die Änderung, um es zu beheben, ist nur >9 zu >10 oder was auch immer Sie brauchen zu ändern.

Verwandte Themen