
Ich habe eine große Datei mit mehreren hundert Zeilen. Diese Datei ist durch eine bestimmte Kennung, beispielsweise „ABC“, in mehrere Teile unterteilt. Diese Zeile „ABC“ kommt 6 Mal vor, daher möchte ich 6 Ausgabedateien. Ich kenne mich mit Split und Awk aus, kann aber anscheinend keine Befehlszeile erstellen, die das tut, was ich beschrieben habe. Irgendwelche Ideen?
Hier ist ein Beispiel
ABC
line 1
line 2
line 3
ABC
line 1
line 2
ABC
line1
Ich hätte gerne drei Dateien, wobei ABC die erste Zeile in der neuen Datei ist und endet, bevor das nächste ABC gefunden wird.
Antwort1
Verwenden voncsplit
csplit -z somefile /ABC/ '{*}'
Die Ausgabedateien sind standardmäßig xx00
, , ..., Sie können das Format und die Nummerierung jedoch bei Bedarf ändern - siehexx01
man csplit
Antwort2
NEEDLE=ABC
HAYSTACK=/path/to/bigfile
csplit -f splitfile_ $HAYSTACK /$NEEDLE/ "{$(($(grep -c -- $NEEDLE $HAYSTACK)-1))}"
for file in splitfile_*; do
sed --in-place "s/$NEEDLE//" $file
done
Das obige Verfahren teilt die Datei wie gewünscht auf, unabhängig davon, wie viele Instanzen der Markierungslinie vorhanden sind, und entfernt dann die Markierung aus den resultierenden Dateien. Die Ausgabedateien werden z. B. splitfile_00
, splitfile_01
usw. genannt.
Lassen Sie uns diesen Teil am Ende des csplit
Aufrufs auseinandernehmen: "{$(($(grep -c $NEEDLE HAYSTACK)-1))}"
: Wir verwenden die Subshell, grep
um die Anzahl der Instanzen Ihres Markers in der Datei zu ermitteln und eins abzuziehen. Dadurch erfahren wir csplit
genau, wie viele Teilungen vorgenommen werden.
Beachten Sie, dass, wie geschrieben, etwas schiefgehen kann, wenn Ihr Marker in den Daten erscheint.