Suchen einer fehlenden fortlaufenden Nummer in einer Datendatei

Suchen einer fehlenden fortlaufenden Nummer in einer Datendatei

Wie kann ich eine große Datei mit „fortlaufenden Nummern“ (die nach 16 zurückgesetzt werden) in einer bestimmten Spalte durchsuchen, um eine fehlende Zeile zu finden?

Ich habe eine Datendatei:

col1 col2 col3 col4 col5 1
col1 col2 col3 col4 col5 2
.
.
.
col1 col2 col3 col4 col5 15
col1 col2 col3 col4 col5 16
col1 col2 col3 col4 col5+1 1

wobei die letzte Spalte von 1 bis 16 zählt und dann wieder auf 1 zurückgesetzt wird. An diesem Punkt wird 1 zu Spalte 5 hinzugefügt.

Eine saubere Ausgabe würde einfach bis zum Ende der Datei iterieren. Wie kann ich fehlende Daten finden, z. B.

col1 col2 col3 col4 col5 1
col1 col2 col3 col4 col5 3

wo eine Zeile übersprungen/verloren gegangen ist, wie aus der letzten Spalte ersichtlich ist, in der der Wert 2 übersprungen wurde?

Als gewünschte Ausgabe hätte ich gerne die Zeilennummer/Position der Zeile vor bzw. nach den fehlenden Daten.

Diese Antwort auf Stack Overflowbrachte mich auf die Idee, zu verwenden awk. Also ist mir Folgendes eingefallen:

awk '$6!=p+1{print NR}{p=$6}'

Versuchen Sie, die aktuelle Zeilennummer zu drucken, wenn Spalte 6 der aktuellen Zeile nicht gleich Spalte 6 der letzten Zeile +1 ist. Dies schlägt fehl, da es zu einer Schleife kommt, die bis 16 geht und dann wieder zurück zu 1.

Antwort1

$ cat -n file
 1  col1 col2 col3 col4 col5 14
 2  col1 col2 col3 col4 col5 15
 3  col1 col2 col3 col4 col5 16
 4  col1 col2 col3 col4 col5 1
 5  col1 col2 col3 col4 col5 2
 6  col1 col2 col3 col4 col5 15
 7  col1 col2 col3 col4 col5 16
 8  col1 col2 col3 col4 col5 4
 9  col1 col2 col3 col4 col5 5

$ awk '{if (p % 16 + 1 != $6) printf("line %d is bad: %s\n", NR, $0); p=$6}' file
line 1 is bad: col1 col2 col3 col4 col5 14
line 6 is bad: col1 col2 col3 col4 col5 15
line 8 is bad: col1 col2 col3 col4 col5 4

Um den Wert des Modulo-Operators „%“ (Divisionsrest) zu verstehen, können Sie mit diesem Awk-Snippet herumspielen:

$ yes | head -n 40 | awk '{x=NR-1; print x, "->", x % 16}'
0 -> 0
1 -> 1
2 -> 2
[...]
14 -> 14
15 -> 15
16 -> 0
17 -> 1
18 -> 2
[...]

verwandte Informationen