Kleine Sortieraufgabe

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
whisper
Beiträge: 3379
Registriert: 23.09.2002 14:32:21
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Kleine Sortieraufgabe

Beitrag von whisper » 24.08.2020 20:02:38

Ziel ist eine Kalendarische Reihenfolge der domains deren Zertifikat bald abläuft.

Gegeben

Code: Alles auswählen

# cat testdaten.txt # vereinfacht und verkürzte liste

ba.de :notAfter=Oct 21 15:59:04 2020 GMT
le.de :notAfter=Aug  1 23:59:59 2020 GMT
bi.de :notAfter=Nov  2 00:04:15 2021 GMT
ro.de :notAfter=Nov  3 15:23:46 2020 GMT
bu.de :notAfter=Nov  5 09:23:14 2020 GMT
zo.de :notAfter=Nov  8 18:45:52 2020 GMT
da.de :notAfter=Oct 13 08:00:29 2020 GMT
he.org :notAfter=Oct 18 17:27:55 2021 GMT

Mit sort -k5 kann ich nach dem Jahr sortieren, mit weiteren Felden in der Key List sollte ich in der Lage sein, das gesamte Datum als Sortierkriterium zu nutzen. Aber das klappt nicht so einfach.
Einfacher wäre das wandeln nach timestamp, sortieren, rückwandeln.
Aber gibt es vielleicht nicht doch eine Lösung nur mit sort?
Alter ist übrigens keine Ausrede, nur Erfahrung, die sich stapelt. 😉

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Kleine Sortieraufgabe

Beitrag von Meillo » 24.08.2020 20:37:00

Code: Alles auswählen

sed 's/=/= /' | LC_DATE=C sort  -k6n,6 -k3M,3 -k4n,5 | sed 's/= /=/'
Zum Verstaendnis: `-k5' sortiert nicht nach Feld 5 sondern nach dem was von Feld 5 bis ans Zeilenende steht. Um *nur* nach Feld 5 zu sortieren, muss man `-k5,5' verwenden.

Zudem beachte man die Sortierart-Kuerzel nach den Feldnummern. `M' ist AFAIR eine GNU-Erweiterung zum Sortieren nach Monatsnamen. `LC_DATE' setze ich weil die Monatskuerzel auf Englisch sind.

Sed nur um aus dem Monat ein eigenes Feld zu machen.


EDIT:

Hier noch eine Variante, die ohne sed auskommt:

Code: Alles auswählen

LC_DATE=C sort -k5n,5 -k2.11M,2 -k3n,4
(Im zweiten Feld wird erst ab dem 11. Zeichen sortiert, es wird also ``:notAfter='' uebersprungen.)
Use ed once in a while!

tobo
Beiträge: 2349
Registriert: 10.12.2008 10:51:41

Re: Kleine Sortieraufgabe

Beitrag von tobo » 24.08.2020 21:06:46

Meillo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 20:37:00
(Im zweiten Feld wird erst ab dem 11. Zeichen sortiert, es wird also ``:notAfter='' uebersprungen.)
Was aber nicht passiert (Nov vor Oct). Wenn man --debug mitgibt, erkennt man, dass man erst ab dem 12. Zeichen den Monat erhält!?

Benutzeravatar
whisper
Beiträge: 3379
Registriert: 23.09.2002 14:32:21
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Re: Kleine Sortieraufgabe

Beitrag von whisper » 24.08.2020 21:08:20

Cool, danke auch für die Erläuterung!
:THX: @Meillo
Alter ist übrigens keine Ausrede, nur Erfahrung, die sich stapelt. 😉

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Kleine Sortieraufgabe

Beitrag von Meillo » 24.08.2020 21:33:05

tobo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 21:06:46
Meillo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 20:37:00
(Im zweiten Feld wird erst ab dem 11. Zeichen sortiert, es wird also ``:notAfter='' uebersprungen.)
Was aber nicht passiert (Nov vor Oct). Wenn man --debug mitgibt, erkennt man, dass man erst ab dem 12. Zeichen den Monat erhält!?
Deine Aussage kann ich nicht nachvollziehen. Bei mir tut's:

Code: Alles auswählen

B-) <in LC_DATE=C sort -k5n,5 -k2.11M,2 -k3n,4       
le.de :notAfter=Aug  1 23:59:59 2020 GMT
da.de :notAfter=Oct 13 08:00:29 2020 GMT
ba.de :notAfter=Oct 21 15:59:04 2020 GMT
ro.de :notAfter=Nov  3 15:23:46 2020 GMT
bu.de :notAfter=Nov  5 09:23:14 2020 GMT
zo.de :notAfter=Nov  8 18:45:52 2020 GMT
he.org :notAfter=Oct 18 17:27:55 2021 GMT
bi.de :notAfter=Nov  2 00:04:15 2021 GMT

B-) 
Wenn ich nachzaehle (beginnend mit 1) faengt der Monat auch ab dem 11 Zeichen an. (Mein sort(1) kennt kein `--debug'.)

Keine Ahnung was bei dir los ist. Kannst du mal Terminalausgaben posten?
Use ed once in a while!

tobo
Beiträge: 2349
Registriert: 10.12.2008 10:51:41

Re: Kleine Sortieraufgabe

Beitrag von tobo » 24.08.2020 21:47:36

In t.txt sind die kopierten Beispieldaten. Bei mir greift der Monat erst mit Zeichen 12, der Cursor zeigt auf das =-Zeichen. Die voranstehenden Leerzeichen haben Relevanz, wie die Fehlermeldung vermuten lässt. Setze ich noch ein weiteres Leerzeichen vor Feld 2 (in t.txt) dann wandert der Cursor auch vor das =-Zeichen. Im Einsatz ist hier ein Stretch mit Coreutils 8.26.

Code: Alles auswählen

$ LC_DATE=C sort --debug -k5n,5 -k2.11M,2 -k3n,4 t.txt
sort: using simple byte comparison
sort: leading blanks are significant in key 2; consider also specifying 'b'
sort: key 3 is numeric and spans multiple fields
le.de :notAfter=Aug  1 23:59:59 2020 GMT
                                ____
               ^ no match for key
                     _
________________________________________
ro.de :notAfter=Nov  3 15:23:46 2020 GMT
                                ____
               ^ no match for key
                     _
________________________________________
bu.de :notAfter=Nov  5 09:23:14 2020 GMT
                                ____
               ^ no match for key
                     _
________________________________________
zo.de :notAfter=Nov  8 18:45:52 2020 GMT
                                ____
               ^ no match for key
                     _
________________________________________
da.de :notAfter=Oct 13 08:00:29 2020 GMT
                                ____
               ^ no match for key
                    __
________________________________________
ba.de :notAfter=Oct 21 15:59:04 2020 GMT
                                ____
               ^ no match for key
                    __
________________________________________
bi.de :notAfter=Nov  2 00:04:15 2021 GMT
                                ____
               ^ no match for key
                     _
________________________________________
he.org :notAfter=Oct 18 17:27:55 2021 GMT
                                 ____
                ^ no match for key
                     __
_________________________________________
$
Und mit 12 oder alternativ mit -k2.11Mb,2:

Code: Alles auswählen

$ LC_DATE=C sort --debug -k5n,5 -k2.12M,2 -k3n,4 t.txt
sort: using simple byte comparison
sort: leading blanks are significant in key 2; consider also specifying 'b'
sort: key 3 is numeric and spans multiple fields
le.de :notAfter=Aug  1 23:59:59 2020 GMT
                                ____
                ___
                     _
________________________________________
da.de :notAfter=Oct 13 08:00:29 2020 GMT
                                ____
                ___
                    __
________________________________________
ba.de :notAfter=Oct 21 15:59:04 2020 GMT
                                ____
                ___
                    __
________________________________________
ro.de :notAfter=Nov  3 15:23:46 2020 GMT
                                ____
                ___
                     _
________________________________________
bu.de :notAfter=Nov  5 09:23:14 2020 GMT
                                ____
                ___
                     _
________________________________________
zo.de :notAfter=Nov  8 18:45:52 2020 GMT
                                ____
                ___
                     _
________________________________________
he.org :notAfter=Oct 18 17:27:55 2021 GMT
                                 ____
                 ___
                     __
_________________________________________
bi.de :notAfter=Nov  2 00:04:15 2021 GMT
                                ____
                ___
                     _
________________________________________
$
Das Ergebnis ist dann also vom verwendeten sort abhängig.

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Kleine Sortieraufgabe

Beitrag von Meillo » 24.08.2020 22:27:11

Dieses `--debug' ist ja richtig hilfreich! :THX:

Mein sort (aus den Coreutils 8.14) hat uebrigens doch ein `--debug'. Hatte bloss vergessen, dass ich (aus irgendwelchen ebenso vergessenen Gruenden) das Heirloom sort davor im Pfad habe. :oops:

tobo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 21:47:36
In t.txt sind die kopierten Beispieldaten. Bei mir greift der Monat erst mit Zeichen 12, der Cursor zeigt auf das =-Zeichen. Die voranstehenden Leerzeichen haben Relevanz, wie die Fehlermeldung vermuten lässt. Setze ich noch ein weiteres Leerzeichen vor Feld 2 (in t.txt) dann wandert der Cursor auch vor das =-Zeichen.
Hier nun des Raetsels Loesung:

Code: Alles auswählen

B-) sed q in2 | LC_DATE=C /usr/bin/sort --debug -k5n,5 -k2.1M,2 -k3n,4
/usr/bin/sort: using `en_US.UTF-8' sorting rules
/usr/bin/sort: key 3 is numeric and spans multiple fields
ba.de :notAfter=Oct 21 15:59:04 2020 GMT
                                ____
      ^ no match for key
                    __
________________________________________

B-) sed q in2 | LC_DATE=C /usr/bin/sort --debug -k5n,5 -k2.2M,2 -k3n,4
/usr/bin/sort: using `en_US.UTF-8' sorting rules
/usr/bin/sort: leading blanks are significant in key 2; consider also specifying `b'
/usr/bin/sort: key 3 is numeric and spans multiple fields
ba.de :notAfter=Oct 21 15:59:04 2020 GMT
                                ____
      ^ no match for key
                    __
________________________________________

B-) sed q in2 | LC_DATE=C /usr/bin/sort --debug -k5n,5 -k2.2bM,2 -k3n,4
/usr/bin/sort: using `en_US.UTF-8' sorting rules
/usr/bin/sort: key 3 is numeric and spans multiple fields
ba.de :notAfter=Oct 21 15:59:04 2020 GMT
                                ____
       ^ no match for key
                    __
________________________________________
Wenn ich vom ersten zum zweiten Zeichen wechsle, dann wird ploetzlich der leading Whitespace relevant. Wenn ich den dann mit `b' ignoriere, tut es wie es soll.

(Warum aber `-k2.1M,2' auf den Doppelpunkt zeigt und nicht auf den Space davor, ist mir noch unverstaendlich.)

(Auch nicht verstehe ich, warum ein `-b' als erste Option nicht auf alle Sortierfelder wirkt, wie in POSIX beschrieben. Bei mir klappt's nur wenn ich es bei jedem relevanten Feld angebe.)


Hier POSIX:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html hat geschrieben: -b Ignore leading <blank> characters when determining the starting and ending
positions of a restricted sort key. If the -b option is specified before
the first -k option, it shall be applied to all -k options. Otherwise, the
-b option can be attached independently to each -k field_start or field_end
option-argument (see below).

[...]

A field comprises a maximal sequence of non-separating characters and, in the
absence of option -t, any preceding field separator
.

[...]

If the -b option or b type modifier is in effect, characters within a field
shall be counted from the first non- <blank> in the field. (This shall apply
separately to first_character and last_character.)

Also, nochmal in verstaendlicheren Worten: Wenn man den Default-Separator verwendet (= beliebiger Whitespace), dann ist dieser Separator-Whitespace Teil des Feldes wenn man Character-Positionen verwendet! Mit `-b' bzw. `b' verhindert man das.

Vermutlich sollte man stets `-b' verwenden, weil das zumeist eher gewollt sein wird.


(Irgendwie kommt mir das nun etwas bekannt vor ... wie wenn wir genau den Fall hier vor ein paar Jahren schonmal gehabt haetten ... :roll: )
Use ed once in a while!

tobo
Beiträge: 2349
Registriert: 10.12.2008 10:51:41

Re: Kleine Sortieraufgabe

Beitrag von tobo » 24.08.2020 23:25:14

Meillo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 22:27:11
(Auch nicht verstehe ich, warum ein `-b' als erste Option nicht auf alle Sortierfelder wirkt, wie in POSIX beschrieben. Bei mir klappt's nur wenn ich es bei jedem relevanten Feld angebe.)
Bei mir auch und beim sort von suckless (9base) ist das Verhalten auch so. Wenn man es weiß, dann kann man sich darauf einstellen. Solange, bis man es dann wieder vergisst. Bei Zeichenpräzisierung im -k dann also einfach ein b verwenden.
Das überspannende Tag-Uhrzeit -k3n,4 funktioniert so allerdings auch nicht. (erkennbar, wenn man den Tag gleichsetzt und eine gleiche 10erStunde setzt, danach unterschiedliche Zeit). Vielleicht dann also sowas:

Code: Alles auswählen

LC_DATE=C sort -k5n,5 -k2.11Mb,2 -k3n,3 -k4,4 FILE
.

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Kleine Sortieraufgabe

Beitrag von Meillo » 25.08.2020 08:30:53

tobo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 23:25:14
Meillo hat geschrieben: ↑ zum Beitrag ↑
24.08.2020 22:27:11
(Auch nicht verstehe ich, warum ein `-b' als erste Option nicht auf alle Sortierfelder wirkt, wie in POSIX beschrieben. Bei mir klappt's nur wenn ich es bei jedem relevanten Feld angebe.)
Bei mir auch und beim sort von suckless (9base) ist das Verhalten auch so. Wenn man es weiß, dann kann man sich darauf einstellen. Solange, bis man es dann wieder vergisst.
Du sagst es! :roll:
Bei Zeichenpräzisierung im -k dann also einfach ein b verwenden.
Das überspannende Tag-Uhrzeit -k3n,4 funktioniert so allerdings auch nicht. (erkennbar, wenn man den Tag gleichsetzt und eine gleiche 10erStunde setzt, danach unterschiedliche Zeit). Vielleicht dann also sowas:

Code: Alles auswählen

LC_DATE=C sort -k5n,5 -k2.11Mb,2 -k3n,3 -k4,4 FILE
.
Ja, das sieht besser aus, wobei genaugenommen auch noch das Feld 4 ein `b' haben sollte. (Nur numerische Felder brauchen kein `b' weil bei denen die Zahl rausgeparst wird und damit leading Whitespace automatisch ignoriert wird.) Damit waere ich dann bei:

Code: Alles auswählen

LC_DATE=C sort -k5n,5 -k2.11bM,2 -k3n,3 -k4b,4


Btw: Ich bin immer wieder ueberrascht wie komplex die Problemstellung des Sortierens ist. Sort(1) ist ja nicht zum Spass so umfangreich. ... ob ich es je ganz verstehen werde? :roll:
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13911
Registriert: 09.04.2008 12:48:59

Re: Kleine Sortieraufgabe

Beitrag von hikaru » 25.08.2020 09:01:02

Verständnisfrage:
Die Sortierung der Monatskürzel erfolgt ja offenbar kalendarisch (wie es sein soll) und nicht alphabetisch (wie ich es eigentlich beim "dummen" Sortieren von Substrings erwartet hätte).
Woher hat sort diese Intelligenz? Ist die eingebaut (Wenn ja, woher weiß sort, dass es nun kalendarisch sortieren soll?) oder übersehe ich in dem Schalterwald eine implizite Konversion in Monatsnummern?

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Kleine Sortieraufgabe

Beitrag von Meillo » 25.08.2020 09:22:33

hikaru hat geschrieben: ↑ zum Beitrag ↑
25.08.2020 09:01:02
Verständnisfrage:
Die Sortierung der Monatskürzel erfolgt ja offenbar kalendarisch (wie es sein soll) und nicht alphabetisch (wie ich es eigentlich beim "dummen" Sortieren von Substrings erwartet hätte).
Korrekt.
Woher hat sort diese Intelligenz? Ist die eingebaut (Wenn ja, woher weiß sort, dass es nun kalendarisch sortieren soll?) oder übersehe ich in dem Schalterwald eine implizite Konversion in Monatsnummern?
Das macht das `M'. (Es wird von LC_DATE sprachlich angepasst ... und ist eine Erweiterung, die es in POSIX nicht gibt.)

Monatssortierungen machen eigentlich nur auf Einzelspalten Sinn, darum findest du seltenst `sort -M', dagegen zumeist eher `sort -k3M,3' bzw. `sort -k3,3M' (was gleichbedeutend ist).
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13911
Registriert: 09.04.2008 12:48:59

Re: Kleine Sortieraufgabe

Beitrag von hikaru » 25.08.2020 10:17:30

Danke!

Antworten