2012-07-28 6 views
8

Ich habe eine Eingabedatei, die so aussieht (erste Spalte ist eine Ortsnummer und die zweite ist eine Anzahl, die im Laufe der Zeit zunehmen sollte) :awk Lösung zum Vergleichen der aktuellen Zeile mit der nächsten Zeile und Drucken einer der Zeilen basierend auf einer Bedingung

1  0 
1  2 
1  6 
1  7 
1  7 
1  8 
1  7 
1  7 
1  9 
1  9 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 

und ich möchte es so aussehen beheben wie folgt aus (Ersatz zählt die mit der vorherigen Zählung verringert):

1  0 
1  2 
1  6 
1  7 
1  7 
1  8 
1  8 
1  8 
1  9 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 

ich awk dafür zu verwenden, habe versucht, aber bin Stolpern mit getline, da ich nicht herausfinden kann, wie man die Zeilennummer zurücksetzt (NR?), so wird es r ead jede Zeile und es ist nächste Zeile, nicht zwei Zeilen gleichzeitig. Dies ist der Code, den ich bisher habe, irgendwelche Ideen?

awk '{a=$1; b=$2; getline; c=$1; d=$2; if (a==c && b<=d) print a"\t"b; else print c"\t"d}' original.txt > fixed.txt 

Dies ist auch der Ausgang ich zur Zeit bin immer:

1  0 
1  6 
1  7 
1  7 
1  9 
1  10 
1  9 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
+0

Ok, nur um zu verdeutlichen, versuchst du * die * Zeilen zu überspringen, wo die Anzahl abnimmt? Das sind viele Zeilen, ich frage mich, ob Sie ein kürzeres Beispiel geben könnten, das genauso klar wäre? – Levon

+0

Entschuldigung, wenn meine Erklärung nicht klar war, möchte ich die vorherige Zeile drucken, wenn die Anzahl abnimmt, also mit der gleichen Anzahl von Zeilen, aber mit einer Datei, in der die Anzahl bleibt oder erhöht, aber nie abnimmt. – suegene

+0

Ich habe es .. überprüfen Sie die Antworten unten, ich glaube, Sie werden finden, was Sie gesucht haben. – Levon

Antwort

7

Vielleicht alles, was Sie wollen, ist:

awk '$2 < p { $2 = p } { p = $2 } 1' input-file 

Dies wird in der ersten Zeile fehlschlagen, wenn der Wert in die zweite Spalte ist negativ, also:

awk 'NR > 1 && $2 < p ...' 

Dadurch wird die zweite Spalte einfach auf den vorherigen Wert gesetzt, wenn der aktuelle Wert kleiner ist. Anschließend wird der aktuelle Wert in der Variablen p gespeichert und die Linie gedruckt.

Beachten Sie, dass dies auch den Abstand der Ausgabe bei sich ändernden Zeilen geringfügig ändert. Wenn Sie Ihre Eingabe wird durch Tabula getrennt, könnten Sie tun möchten:

awk 'NR > 1 && $2 < p { $2 = p } { p = $2 } 1' OFS=\\t input-file 
+0

Wow .. so viel prägnanter .. Ich denke, ich habe die ausführliche Version Ihrer ersten Lösung – Levon

+0

Fantastisch, ich habe nur versucht, den Abstand heraus zu finden, danke! – suegene

2

Dieses Skript wird tun, was Sie möchten:

{ 
    if ($2 < prev_count) 
    $2 = prev_count 
    else 
    prev_count = $2 

    printf("%d %d\n", $1, $2) 
} 

Dies ist eine ausführlichere Version ist leicht lesbar :)

+0

Danke, ich schätze die ausführliche Version auch! – suegene

+0

@suegene Glücklich zu helfen .. Ich habe den Ausgabeabstand mit 'printf' angepasst, was Ihnen eine etwas feinere Kontrolle über das Format/den Abstand geben kann, wenn Sie es brauchen. – Levon