Ich habe eine buchähnliche Liste von Zeilen, sagen wir
day
satur-
sun-
holy-
night
ball
to-
eve
election
christmas
Nun möchte ich diese Zeilen auf die naheliegende Weise sortieren: Ich möchte jeden „übergeordneten“ Eintrag ( day
, night
, eve
) mit den entsprechenden eingerückten „untergeordneten“ Einträgen ( satur-
, sun-
, …) gruppieren und diese Gruppen nach ihrem übergeordneten Eintrag sortieren. Ich möchte auch die untergeordneten Einträge innerhalb einer gegebenen Gruppe sortieren.
Die gewünschte Ausgabe ist daher:
day
holy-
satur-
sun-
eve
christmas
election
night
ball
to-
Wie erreiche ich dies am besten mithilfe von Unix-Kerntools wie sort
?
Antwort1
Sie können ein Zeichen auswählen, das in Ihrer Textdatei wahrscheinlich nicht vorkommt, den übergeordneten Namen + dieses Zeichen jeder untergeordneten Zeile voranstellen, sortieren und dann den übergeordneten Namen und das Trennzeichen aus jeder untergeordneten Zeile entfernen, z. B. mit gnu
sed und einem niedrigen ASCII-Zeichen wie\x02
sed '/^[^[:blank:]]/h;//!G;s/\(.*\)\n\(.*\)/\2\x02\1/' infile | sort | sed 's/.*\x02//'
Funktionsweise:
Der 1. sed
führt folgende Aktionen aus:
/^[^[:blank:]]/h
- nicht eingerückte Zeilen (übergeordnete Zeilen) über den Leerraum kopieren
//!G
- bei eingerückten Zeilen (untergeordnete Zeilen) den Inhalt des Leerraums an den Musterraum anhängen
s/\(.*\)\n\(.*\)/\2\x02\1/
- Zeilen im Musterraum vertauschen, die \n
neue Zeile durch \x02
das Folgende ersetzen sort
und alles bis einschließlich \x02
mit einem 2. entfernensed 's/.*\x02//'