(gelöst) Wie kann ich das sortieren?
(gelöst) Wie kann ich das sortieren?
Wie kann ich diese Zeilen sortieren:
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein zwei drei vier Wort. (Xwort)
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein Wort. (Uwort)
... damit ich dieses Sortier-Ergebnis erreiche:
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein Wort. (Uwort)
2.194 Ein zwei drei vier Wort. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
Sortiert wird zuerst die erste Spalte z. B. 2.194 und so weiter und als zweiten und letzten Sortiervorgang nach dem letzten Wort der Zeile z. B. (Dwort).
Wenn ich meinen Text in eine Excel Tabelle kopiere und in Excel sortiere ist es kein Problem. Mit sort schaffe ich es nicht. Es ergibt nur Chaos. Wie sortiere ich mit sort?
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein zwei drei vier Wort. (Xwort)
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein Wort. (Uwort)
... damit ich dieses Sortier-Ergebnis erreiche:
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein Wort. (Uwort)
2.194 Ein zwei drei vier Wort. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
Sortiert wird zuerst die erste Spalte z. B. 2.194 und so weiter und als zweiten und letzten Sortiervorgang nach dem letzten Wort der Zeile z. B. (Dwort).
Wenn ich meinen Text in eine Excel Tabelle kopiere und in Excel sortiere ist es kein Problem. Mit sort schaffe ich es nicht. Es ergibt nur Chaos. Wie sortiere ich mit sort?
Zuletzt geändert von medias am 04.05.2017 17:39:30, insgesamt 1-mal geändert.
Re: Wie kann ich das sortieren?
Wie ist das:
Code: Alles auswählen
sort -t '(' -k1n -k2
Re: Wie kann ich das sortieren?
Vielleicht eher so?
Code: Alles auswählen
sort -t "." -k1n,1 -k3
Re: Wie kann ich das sortieren?
Dann reißt du aber die Dezimalzahl auseinander!?
Dann eher so:
Dann eher so:
Code: Alles auswählen
sort -t "." -k1n -k3
Re: Wie kann ich das sortieren?
@tobo
Wenn ich das nicht falsch sehe (z. B. wg. Übermüdung ), sortieren Deine beiden Vorschläge nicht im Sinne des Fragestellers, da sie die mit "17.1" beginnenden Zeilen vor die mit "2.194" sortieren statt dahinter?!
Wenn ich das nicht falsch sehe (z. B. wg. Übermüdung ), sortieren Deine beiden Vorschläge nicht im Sinne des Fragestellers, da sie die mit "17.1" beginnenden Zeilen vor die mit "2.194" sortieren statt dahinter?!
Re: Wie kann ich das sortieren?
Also hier kommt das schon richtig raus!? 2.194 zuerst...
Re: Wie kann ich das sortieren?
Merkwürdig! Aus meinem Terminal kopiert:
Code: Alles auswählen
$ cat beispiel.txt
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein zwei drei vier Wort. (Xwort)
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein Wort. (Uwort)
$ sort -t '(' -k1n -k2 beispiel.txt
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein Wort. (Uwort)
2.194 Ein zwei drei vier Wort. (Xwort)
Re: Wie kann ich das sortieren?
Und das aus meinem:
XTerm(327); sort (GNU coreutils) 8.23 bzw. Heirloom Toolchest; LC_COLLATE=C; der Rest LC_*=en_US.UTF-8
PS: Wegen der numerischen Sortierung muss das ja eigentlich auch nicht auf das erste Feld (mit ,1) beschränkt werden!? Anders wäre es, wenn hier nach Zeichen sortiert werden würde.
Code: Alles auswählen
$ cat beispiel.txt
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein zwei drei vier Wort. (Xwort)
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein Wort. (Uwort)
$ sort -t '(' -k1n -k2 beispiel.txt
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein Wort. (Uwort)
2.194 Ein zwei drei vier Wort. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
PS: Wegen der numerischen Sortierung muss das ja eigentlich auch nicht auf das erste Feld (mit ,1) beschränkt werden!? Anders wäre es, wenn hier nach Zeichen sortiert werden würde.
Re: Wie kann ich das sortieren?
Diese Reihenfolge kann ich nicht nachvollziehen. Wenn die erste Spalte numerisch sortiert wird, dann sollte das nie zu diesem Ergebnis fuehren, egal in welchem Locale. (Irgendwas scheine ich noch zu uebersehen ... oder es war keine 1:1-Kopie der Shellsession ...)maroc hat geschrieben:Merkwürdig! Aus meinem Terminal kopiert:Code: Alles auswählen
$ cat beispiel.txt 17.1 Eins zwei drei vier fünf Worte. (Dwort) 17.1 Eins zwei vier fünf Worte. (Xwort) 17.1 Eins zwei drei vier fünf sechs Worte. (Awort) 17.1 Eins zwei drei vier sechs Worte. (Uwort) 2.194 Ein zwei Wort. (Dwort) 2.194 Ein zwei drei vier Wort. (Xwort) 2.194 Ein fünf sechs Wort. (Awort) 2.194 Ein Wort. (Uwort) $ sort -t '(' -k1n -k2 beispiel.txt 17.1 Eins zwei drei vier fünf sechs Worte. (Awort) 17.1 Eins zwei drei vier fünf Worte. (Dwort) 17.1 Eins zwei drei vier sechs Worte. (Uwort) 17.1 Eins zwei vier fünf Worte. (Xwort) 2.194 Ein fünf sechs Wort. (Awort) 2.194 Ein zwei Wort. (Dwort) 2.194 Ein Wort. (Uwort) 2.194 Ein zwei drei vier Wort. (Xwort)
Natuerlich ist das Locale LC_COLLATE bei sort(1) grundsaetzlich immer entscheidend, darum sollte das bei solchen Aufgaben immer explizit gesetzt werden.
Aus meiner Sicht hat tobo passende Antworten geliefert.
Use ed once in a while!
-
- Beiträge: 134
- Registriert: 03.02.2011 11:11:21
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Frankfurt
Re: Wie kann ich das sortieren?
Und LC_NUMERIC nicht vergessen:Meillo hat geschrieben:Natuerlich ist das Locale LC_COLLATE bei sort(1) grundsaetzlich immer entscheidend, darum sollte das bei solchen Aufgaben immer explizit gesetzt werden.
Code: Alles auswählen
$ LC_NUMERIC="de_DE.UTF-8" sort -t '(' -k1n -k2 bsp.txt
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein Wort. (Uwort)
2.194 Ein zwei drei vier Wort. (Xwort)
$ LC_NUMERIC=C sort -t '(' -k1n -k2 bsp.txt
2.194 Ein fünf sechs Wort. (Awort)
2.194 Ein zwei Wort. (Dwort)
2.194 Ein Wort. (Uwort)
2.194 Ein zwei drei vier Wort. (Xwort)
17.1 Eins zwei drei vier fünf sechs Worte. (Awort)
17.1 Eins zwei drei vier fünf Worte. (Dwort)
17.1 Eins zwei drei vier sechs Worte. (Uwort)
17.1 Eins zwei vier fünf Worte. (Xwort)
Code: Alles auswählen
LC_NUMERIC="de_DE.UTF-8" sed 's/\./,/' bsp.txt | sort -t '(' -k1n -k2 | sed 's/,/./'
Re: Wie kann ich das sortieren?
Danke, das macht tatsächlich den Unterschied. Ich hatte LC_NUMERIC="de_DE.UTF-8", und da wird das Komma (statt des Punktes) als Dezimaltrenner verwendet.newdeb hat geschrieben:Und LC_NUMERIC nicht vergessen:
Re: Wie kann ich das sortieren?
Ja, danke!newdeb hat geschrieben: Und LC_NUMERIC nicht vergessen:
Nein, so:Oder auch soCode: Alles auswählen
LC_NUMERIC="de_DE.UTF-8" sed 's/\./,/' bsp.txt | sort -t '(' -k1n -k2 | sed 's/,/./'
Code: Alles auswählen
sed 's/\./,/' bsp.txt | LC_NUMERIC="de_DE.UTF-8" sort -t '(' -k1n -k2 | sed 's/,/./'
Use ed once in a while!
Re: Wie kann ich das sortieren?
Aber ich versteh's immer noch nicht. Ist es nicht so, dass bei numerischer Sortierung der String in eine Zahl konvertiert wird, und zwar (wie bei atoi(3)) der Anfang des Strings bis zum ersten Nicht-Zahl-Zeichen. Im englischen Fall waere das erste Nicht-Zahl-Zeichen der Space und damit findet man die Zahlen ``2.194'' bzw. ``17.1''. Im deutschen Fall ist das erste Nicht-Zahl-Zeichen der Punkt und damit findet man nur ``2'' und ``17''. In beiden Faellen waere aber die 2 numerische kleiner, egal ob mit oder ohne die Kommastellen.maroc hat geschrieben:Danke, das macht tatsächlich den Unterschied. Ich hatte LC_NUMERIC="de_DE.UTF-8", und da wird das Komma (statt des Punktes) als Dezimaltrenner verwendet.newdeb hat geschrieben:Und LC_NUMERIC nicht vergessen:
Versteht ihr mein Problem beim Nachvollziehen der Ausgabe?
... ausser, bei ``2.194'' wird der Punkt als Tausendertrenner interpraetiert, weil genau drei Stellen folgen, was bei ``17.1'' nicht der Fall ist. Damit waere der Vergleich zwischen ``2194'' und ``17'', wovon natuerlich ersteres groesser ist.
Hey, da sollte ich jetzt eintauchen! Das hoert sich super interessant an. Auch will ich schon lange in POSIX studieren wie das bei sort(1) genau funktioniert ... Hoffentlich finde ich dazu die Zeit.
Use ed once in a while!
Re: Wie kann ich das sortieren?
In meinem, allerdings laienhaften, Verständnis sieht es so aus, als ob sort im deutschen Fall den Punkt einfach ignoriert, warum auch immer. Deshalb sortiert "17.1" (171) vor "2.194" (2194), aber etwa "2.1" (21) vor "17.1" (171).Meillo hat geschrieben:Ist es nicht so, dass bei numerischer Sortierung der String in eine Zahl konvertiert wird, und zwar (wie bei atoi(3)) der Anfang des Strings bis zum ersten Nicht-Zahl-Zeichen. Im englischen Fall waere das erste Nicht-Zahl-Zeichen der Space und damit findet man die Zahlen ``2.194'' bzw. ``17.1''. Im deutschen Fall ist das erste Nicht-Zahl-Zeichen der Punkt und damit findet man nur ``2'' und ``17''. In beiden Faellen waere aber die 2 numerische kleiner, egal ob mit oder ohne die Kommastellen.
Code: Alles auswählen
$ echo -e "17.1\n2.194" | sort -n
17.1
2.194
$ echo -e "17.1\n2.1" | sort -n
2.1
17.1
Meillo hat geschrieben:... ausser, bei ``2.194'' wird der Punkt als Tausendertrenner interpraetiert, weil genau drei Stellen folgen, was bei ``17.1'' nicht der Fall ist.
Re: Wie kann ich das sortieren?
Mit der Vermutung habe ich ziemlich sicher recht, denn hier wird der Tausendertrenner explizit erwaehnt:Meillo hat geschrieben: ... ausser, bei ``2.194'' wird der Punkt als Tausendertrenner interpraetiert, weil genau drei Stellen folgen, was bei ``17.1'' nicht der Fall ist. Damit waere der Vergleich zwischen ``2194'' und ``17'', wovon natuerlich ersteres groesser ist.
Tausendertrenner werden einfach ignoriert als seien sie nicht da, wie hier erahnt werden kann:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html hat geschrieben: -n
Restrict the sort key to an initial numeric string, consisting of optional <blank> characters, optional <hyphen-minus> character, and zero or more digits with an optional radix character and thousands separators (as defined in the current locale), which shall be sorted by arithmetic value.
Code: Alles auswählen
$ printf '102\n1.03\n10.1\n10.0\n1.01\n101'| LC_ALL=de_DE.UTF-8 sort -n
10.0
1.01
101
10.1
102
1.03
Damit als kleine Korrektur zu meiner ersten Vermutung: Es ist egal wie etwaige Tausendertrenner plaziert sind, somit wir im Originalbeispiel zwischen ``2194'' und ``171'' vergleichen.
Use ed once in a while!
Re: Wie kann ich das sortieren?
Also bei mir werden die Trenner nicht vollständig ignoriert!? Als numerischer Trenner schon, aber der Punkt wandert innerhalb der 101er-Gruppe von links nacht rechts:Meillo hat geschrieben:Tausendertrenner werden einfach ignoriert als seien sie nicht da, wie hier erahnt werden kann:Code: Alles auswählen
$ printf '102\n1.03\n10.1\n10.0\n1.01\n101'| LC_ALL=de_DE.UTF-8 sort -n 10.0 1.01 101 10.1 102 1.03
Code: Alles auswählen
$ printf '102\n1.03\n10.1\n10.0\n1.01\n101'| LC_ALL=de_DE.UTF-8 sort -n
10.0
101
1.01
10.1
102
1.03
Code: Alles auswählen
$ printf '10.001\n100.01\n1.0001\n1000.1\n10001\n'| LC_ALL=de_DE.UTF-8 sort -n
10001
1.0001
10.001
100.01
1000.1
Re: Wie kann ich das sortieren?
Ich wuerde das als Implementierungsbesonderheit werten.tobo hat geschrieben: Also bei mir werden die Trenner nicht vollständig ignoriert!? Als numerischer Trenner schon, aber der Punkt wandert innerhalb der 101er-Gruppe von links nacht rechts:
Wenn alle ``Darstellungen'' innerhalb der 101er-Gruppe als zahlenmaessig gleichwertig erachtet werden, dann ist undefiniert in welcher Reihenfolge sie kommen ... ausser du verwendest `-s' (stabilized sort), dann sollten sie in der Reihenfolge der Eingabe erscheinen.
Use ed once in a while!
Re: Wie kann ich das sortieren?
Das mag sein. Bei mir tritt diese Besonderheit jedoch in der GNU-, Heirloom, Busybox- und Suckless-Variante von sort auf. Welches sort erzeugte denn bei dir die Ausgabe?Meillo hat geschrieben:Ich wuerde das als Implementierungsbesonderheit werten.
Wenn alle ``Darstellungen'' innerhalb der 101er-Gruppe als zahlenmaessig gleichwertig erachtet werden, dann ist undefiniert in welcher Reihenfolge sie kommen
Re: Wie kann ich das sortieren?
sort (GNU coreutils) 8.13, auf Debian oldstable. (Es koennte evtl. auch am Locale liegen, k.A.: locale (Debian EGLIBC 2.13-38+deb7u11) 2.13)tobo hat geschrieben: Bei mir tritt diese Besonderheit jedoch in der GNU-, Heirloom, Busybox- und Suckless-Variante von sort auf. Welches sort erzeugte denn bei dir die Ausgabe?
Meine Gedanken sind folgende:
Ist der zahlenmaessige Wert von ``10.1'' und ``1.01'' gleich? Wenn ja, dann unterliegt die Reihenfolge nur der Implementierung des Sortieralgorithmuses. Jedenfalls kenne ich keine inhaltliche Logik fuer eine sinnvolle Ordnung dieser zwei invalider Notationen.
Die einzige Regel, die fuer mich Sinn macht, ist das Ignorieren von Tausendertrennern, egal an welchen Stellen sie stehen. (Das ist auch implementatorisch gut umsetzbar ... und damit wahrscheinlich so auch umgesetzt.)
Interessant ist, dass `-nu' die zahlenmaessig gleichen Werte ``10.1'' und ``1.01'' nicht vereint, waehrend ``100'' und ``100,0'' zusammenfallen! ... vielleicht ist das aber auch nur ein undefiniertes Verhalten und die Folge von ``garbage in, garbage out''.
Use ed once in a while!
Re: Wie kann ich das sortieren?
Würden die "vollständig" ignoriert werden, dann sollte doch die Reihenfolge der 101er im printf entscheidend für die Ausgabe sein!? Wie dem auch sei, habe gerade mal sort (coreutils) aus Wheezy getestet und das Ergebnis ist gleich zu Jessie.Meillo hat geschrieben:Die einzige Regel, die fuer mich Sinn macht, ist das Ignorieren von Tausendertrennern, egal an welchen Stellen sie stehen. (Das ist auch implementatorisch gut umsetzbar ... und damit wahrscheinlich so auch umgesetzt.)
Re: Wie kann ich das sortieren?
Nur wenn es ein stabiler Sortieralgorithmus ist, den man bei GNU sort mit `-s' erzwingen kann. Siehe (mit Dezimalkomma):tobo hat geschrieben:Würden die "vollständig" ignoriert werden, dann sollte doch die Reihenfolge der 101er im printf entscheidend für die Ausgabe sein!?Meillo hat geschrieben:Die einzige Regel, die fuer mich Sinn macht, ist das Ignorieren von Tausendertrennern, egal an welchen Stellen sie stehen. (Das ist auch implementatorisch gut umsetzbar ... und damit wahrscheinlich so auch umgesetzt.)
Code: Alles auswählen
:-Q printf '100,0\n100\n' | LC_ALL=de_DE-UTF-8 sort -n
100
100,0
:-Q printf '100,0\n100\n' | LC_ALL=de_DE-UTF-8 sort -ns
100,0
100
Das mag viele Gruende haben. Vielleicht wird intern immer qsort(3) verwendet, das je nach Rechnerarchitektur unterschiedlich implementiert ist ... was weiss ich.Wie dem auch sei, habe gerade mal sort (coreutils) aus Wheezy getestet und das Ergebnis ist gleich zu Jessie.
Mit `-s' sollte das Ergebnis aber immer gleich sein, weil dafuer definiert ist, dass gleiche Werte in der Reihenfolge der Eingabe auszugeben sind. Ohne `-s' ist die Reihenfolge in dem Fall implementierungsspezifisch. Soweit die Theorie.
Use ed once in a while!
Re: Wie kann ich das sortieren?
Danke für die Hilfe. Ich hatte nicht geahnt das es so schwierig sein würde.Meillo hat geschrieben: Nein, so:Code: Alles auswählen
sed 's/\./,/' bsp.txt | LC_NUMERIC="de_DE.UTF-8" sort -t '(' -k1n -k2 | sed 's/,/./'
Das mit der 2.100 (in meinem Fall ist das eine Textziffer) ist auch ein Problem wenn ich diese Tabelle nach Excel importiere. Ich weiss noch nicht warum, aber 2.100 wird dabei 2100. ABER 2.99 bleibt 2.99. Sehr dämlich das!