
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
[...]