
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 auf
split(/^(?=\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 awk
fü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