Wie verwende ich sed, um jedes Vorkommen eines Musters abzüglich eines Falls zu ersetzen?

Wie verwende ich sed, um jedes Vorkommen eines Musters abzüglich eines Falls zu ersetzen?

Ich habe eine temporäre Datei, die jede halbe Stunde von einem Cron-Job generiert wird und die folgende Ausgabe erzeugt:

---- kind=<data> field=<value> humankind=<data> kind=<data> field=<value> humankind=<data> kind=<data> field=<value> humankind=<data>

Ich möchte es so formatieren, dass es folgendermaßen aussieht:

---- kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>

Ich habe die folgenden Sed-Ausdrücke ausprobiert:

sed -r 's|\s(kind=)|\n\1|g' /path/to/file

Die Ausgabe sieht dann aber so aus:

----                                         <------ The first line should be here
kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>

Verwenden Sie diesen Ausdruck:

sed -r 's|[^-]{4} (kind=)|\n\1|g' /path/to/file

Generiert die gewünschte Ausgabe, allerdings mit merkwürdigem Verhalten:

---- kind=<data> field=<value> humankind=<incomplete data>
kind=<data> field=<value> humankind=<incomplete data>
kind=<data> field=<value> humankind=<incomplete data>

Aus irgendeinem Grund druckt das letzte Feld (das einen Teil des im Sed-Ausdruck verwendeten Musters enthält) nur die ersten beiden Zeichen der „unvollständigen Daten“.

Was mache ich falsch?

Antwort1

Das Problem mit sed -r 's|\s(kind=)|\n\1|g' /path/to/fileist, dass Sie für alle Vorkommen von ' kind ', einschließlich des ersten, eine neue Zeile einfügen, sodass Sie nach eine zusätzliche neue Zeile erhalten ----. Versuchen Sie stattdessen

sed -E 's|\s(kind=)|\n\1|2g' /path/to/file

da das erste Spiel übersprungen wird.

Der zweite Versuch schlägt fehl, da er mit den 4 Zeichen vor „kind“ übereinstimmt, und das ist Teil Ihrer Daten (die 6 Zeichen lang sein müssen)!

verwandte Informationen