Datei nach Zeilengruppe sortieren

Datei nach Zeilengruppe sortieren

Wenn ich eine Datei mit ähnlichem Inhalt habe:

FirstSection
    Unique first line in first section
    Unique second line in first section

SecondSection
    Unique first line in second section
    Unique second line in second section

...

NthSection
    Unique first line in Nth section
    Unique second line in Nth section

Ist es möglich, Unix-Befehle (z. B. sort, awk) zu verwenden, um die Datei alphabetisch nach der ersten nicht eingerückten Zeile in jeder Dreizeilengruppe zu sortieren und gleichzeitig die eingerückten Zeilen unter ihrer vorhandenen Gruppe beizubehalten?

Antwort1

Mit Perl könnten Sie etwa Folgendes ausführen:

  • schlürfe die Datei ( perl -0n)
  • Teilen Sie die Eingabe in nicht eingerückte Zeilen aufsplit(/^(?=\S)/m)
  • Sortieren und Drucken

perl -0ne 'print sort split(/^(?=\S)/m) ' ex 

Antwort2

Zuerst setzt sed jeden Abschnitt in eine einzelne Zeile und verwendet den Text <EOL>als Trennzeichen zwischen den Abschnittszeilen. Dann sortiere ich die Abschnitte und verwende das zweite sed, um jeden <EOL>wieder auf eine neue Zeile zurückzusetzen.

sed -r ':r;$!{N;br};s:\n([[:blank:]])(\1*):<EOL>\1\2:g' file|sort|sed -r '/^$/d;:l;G;s:(.*)<EOL>(.*)(\n):\1\3\2:;tl;$s:\n$::'

Ich habe kein Zeichen als Trennzeichen gewählt, da die Eingabedatei eines enthalten könnte. Daher habe ich <EOL>stattdessen Folgendes verwendet.

Ausgabe:Ich habe nach jedem Abschnitt, außer dem letzten, eine neue Zeile hinzugefügt, um den Stil der Eingabedatei neu zu erstellen.

FirstSection
    Unique first line in first section
    Unique second line in first section

NthSection
    Unique first line in Nth section
    Unique second line in Nth section

SecondSection
    Unique first line in second section
    Unique second line in second section

Antwort3

mit GNU awkfür asort()und PROCINFO["sorted_in"]wir könnten jede Gruppe von Datensätzen in einem mit awk verknüpften Array basierend auf dem Zeilenumbruch zwischen jeder Gruppe speichern; dann das Array sortieren asort()und alle Gruppen innerhalb einer For-Schleife ausdrucken.

awk '/^$/{ ++grpNr; next }
{ groups[grpNr]=(groups[grpNr]==""? "" : groups[grpNr] RS) $0 }
END{ asort(groups); 
     for(grp in groups) print groups[grp]
}'  infile

Notiz: Sie können PROCINFO["sorted_in"]das Element verwenden, um festzulegen, welche Art der Sortierung Sie benötigen. Beispielsweise PROCINFO["sorted_in"]="@val_str_desc"sortiert dasWertue unseres Arrays alsstring und inBeschreibungBefehl.


Oder mit any awk(um durch Nul getrennte Datensatzblöcke zu erstellen) + sort -z(um nach dem Nul-Zeichen und nicht nach Newline zu sortieren) + tr(um zuvor durch hinzugefügte Nul-Zeichen zu entfernen awk):

<infile awk '/^$/{ ++grpNr; next }
{ groups[grpNr]=(groups[grpNr]==""? "\0" : groups[grpNr] RS) $0 }
END{ for(grp in groups) print groups[grp] }' |sort -z |tr -d '\0'

Testen anhand einer Eingabedatei wie:

BFirstSection
    Unique first line in first section
    Unique second line in first section

DSecondSection
    Unique first line in second section
    Unique second line in second section

Aanothersection...
    ...
    ...

CfourthSection
    Unique first line in Nth section
    Unique second line in Nth section

Sie erhalten die folgende Ausgabe:

Aanothersection...
    ...
    ...
BFirstSection
    Unique first line in first section
    Unique second line in first section
CfourthSection
    Unique first line in Nth section
    Unique second line in Nth section
DSecondSection
    Unique first line in second section
    Unique second line in second section

verwandte Informationen