• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] Sortieren nach mehreren Spalten mit sort

romi1

Newbie
Hallo!
Ich bitte euch um Hilfe zu folgendem Problem:
Wie sortiert man eine Datei zuerst nach Spalte 7 (ist in diesem Fall die Kostenstelle), dann nach Spalte 3 (= Datum), und dann noch numerisch nach Spalte 1 (= fortlaufende Nummer)? Ich verwende übrigens Suse Linux 10.0, Shell = bash
Mit folgendem Befehl klappt es nicht:

Code:
sort -k 7,7 -k 3,3 -k 1,1 test.txt

Ich würde ja die Datei gerne hochladen, aber es ist in diesem Forum scheinbar nicht erlaubt!?


Der Grund für das Sortierproblem dürfte sein, das je Zeile vor bzw. nach den betreffende Spalten sich eine unterschiedliche Anzahl von Leerzeichen befindet. Das sollte aber dennoch funktionieren, denn das ganze soll in ein Prog. (Shell-Script) stammt teilweise von einer HP-UX-Maschine - dort hat es so geklappt. Das Prog sortiert Daten, die von verschiedenen Personen eingeben werden und da möchte bzw. kann ich nicht die Anzahl der Lehrzeichen zwischen den Spalten vorgeben.

Hat jemand eine Idee?
 

abgdf

Guru
Poste doch bitte mal ein paar Beispielzeilen.
Größere Datenmengen oder größere Skripte kann man auch bequem in sog. "Pastebins" posten, z.B. in

http://paste.pocoo.org/

Viele Grüße
 
OP
R

romi1

Newbie
Hi!

Also hier einige Zeilen:

Code:
   16	x 2008-11-04 es VPA  8.0  011/NSBO Umfahrung Gr. Haslau: Aufnahme Deponie 1, 3, 9 (Urgel?nde)
    17	x 2008-11-05 e  BER  1.5  011/NSBO  Umfahrung Gr. Haslau: Berechnung der Aufnahme Deponie 1, 3, 9 (Urgel?nde)
    18	x 2008-11-06 ii VPA  3.0  011/NSBO Umfahrung Gr. Haslau: Aufnahme Deponie 7 (Urgel?nde)
    19	x 2008-11-06 e  BER  0.5  011/NSBO  Umfahrung Gr. Haslau: Berechnung der Aufnahme Deponie 7 (Urgel?nde)
    20	x 2008-11-06 es VPA  4.5  011/NSBO  Umfahrung Gr. Haslau: Abst. B?schungsneigung + UPL H?hen von Pr. 43-51
    21	x 2008-11-07 es VPA  3.0  011/NSBO  Umfahrung Gr. Haslau: Abst. B?schungsneigung + UPL H?hen von Pr. 52-60 (L68) Abst. Humusabtrag von Pr. 125-127
    22	x 2008-11-07 es VPA  2.0  011/NSBO  Umfahrung Gr. Haslau: Aufnahme Urgel?nde von Pr. 115-127 (B36)
    23	x 2008-11-13 e  BER  0.5  011/NSBO  Umfahrung Gr. Haslau: Berechnung der Urgel?ndeaufnahme
    24	x 2008-11-14 es VPA  3.0  011/NSBO  Umfahrung Gr. Haslau: Absteckung L8234 Teil 2 Humusabtrag + Polygonpunkte gemacht
    25	x 2008-11-14 es VPA  1.0  011/NSBO  Umfahrung Gr. Haslau: Aufnahme Urgel?nde L8234 Teil 2
    26	x 2008-11-17 es VPA  7.0  011/NSBO  Umfahrung Gr. Haslau: Abst. B?schung L68 von Pr.5-17
    27	x 2008-11-19 e  BER  0.5  011/NSBO  Umfahrung Gr. Haslau: Berechnung der Urgel?ndeaufnahme L8234 
    28	x 2008-11-20 es VPA  3.0  011/NSBO  Umfahrung Gr. Haslau: Abst. B?schung von Pr.115-120 
    29	x 2008-11-20 es VPA  3.5  011/NSBO  Umfahrung Gr. Haslau: Aufnahme Urgel?nde bei Deponie Pr.60 und Pr.82 (Swietelsky)  
    30	x 2008-11-20 e  BER  1.0  011/NSBO  Umfahrung Gr. Haslau: Berechnung der  Aufnahme Urgel?nde bei Deponie Pr.60 und Pr.82 (Swietelsky)  
    31	#
    32	x 2008-11-06 s  CAD  0.5  011/NSBO  Umfahrung Gr. Haslau: Pl?ne falten (Br?cke ?ber den Rotbach, Hr. Flicker)
    33	x 2008-11-06 g  CAD  1.5  011/NSBO  Umfahrung Gr. Haslau: Pl?ne falten (Br?cke ?ber den Rotbach, Hr. Flicker)
    34	x 2008-11-06 j  CAD  1.5  011/NSBO  Umfahrung Gr. Haslau: Pl?ne falten (Br?cke ?ber den Rotbach, Hr. Flicker)
    35	x 2008-11-17 es VPA  2.0  011/NSBO  Umfahrung Gr. Haslau: Abst. Br?cke Rotbach, Achsen auf Schnurger?st (Hr. Hollnsteiner)
    36	#
    37	x 2008-11-05 e BER 1.0 011/NGQI ABA Neulengbach: Berechnung der Kanalendaufnahme 
    38	#
    39	x 2008-11-05 j   DIV  3.5  HIL/ZZZZ  B?ro: Eingabe- Belastung- Lieferschein (NTVI - NTVE Oktober)
    40	x 2008-11-13 j   DIV  3.0  HIL/ZZZZ  B?ro: Eingabe- Belastung- Lieferschein (NTVI - NTVE November)
    41	x 2008-11-19 s   DIV  2.0  HIL/ZZZZ  B?ro: Pfl?cke von Lugendorf geholt und eingelagert
    42	x 2008-11-19 e   DIV  1.0  HIL/ZZZZ  B?ro: Grenzmarken von Ebreichsdorf geholt und eingelagert
    43	x 2008-11-19 s   DIV  1.0  HIL/ZZZZ  B?ro: Grenzmarken von Ebreichsdorf geholt und eingelagert
   261	x 2008-11-21 i  CAD  3.5 011/VXDY EKZ+FMZ Gerasdorf: Abrechnungsprofile zeichnen und Massen ermitteln
   262	x 2008-11-24 i  CAD  6.0 011/VXDY EKZ+FMZ Gerasdorf: Abrechnungsprofile zeichnen und Massen ermitteln
   263	x 2008-11-25 i  CAD  4.0 011/VXDY EKZ+FMZ Gerasdorf: Abrechnungsprofile zeichnen und Massen ermitteln
   264	x 2008-11-26 i  CAD  2.0 011/VXDY EKZ+FMZ Gerasdorf: Abrechnungsprofile zeichnen und Massen ermitteln
   265	
   266	x 2008-11-06 i  CAD  2.5 011/NTER A22 LWL Korneuburg-Stockerau: Bestandspl?ne zeichnen
   267	
   268	x 2008-11-08 i  CAD  4.5 011/NSBO Umfahrung Grosshaslau: Absteckliste f?r L68 vorbereiten (Pr 44-60)
   269	x 2008-11-05 i  CAD  0.5  011/NSBO Zmfahrung Grosshaslau: ?bersichtsplan als DWG und PLT liefern
   270	x 2008-11-05 i  CAD  1.0 011/NSBO Umfahrung Grosshaslau: Rotbachbr?cke - Ger?stplan 2x plotten und falten
   271	x 2008-11-06 i  CAD  1.0 011/NSBO Umfahrung Grosshaslau: Rotbachbr?cke - Schalung.- und Bewehrungspl?ne plotten
   272	x 2008-11-06 i  CAD  3.5 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 1, 3, 7 und 9 - Urgel?ndeaufnahme zeichnen
   273	x 2008-11-07 i  CAD  6.5 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 1, 3, 7 und 9 - Profile zeichnen
   274	x 2008-11-10 i  CAD  10.0 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 1, 3, 7 und 9 - Profile zeichnen und Massen berechnen
   275	x 2008-11-11 i  CAD  1.5 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 1, 3, 7 und 9 - Profile zeichnen und Massen berechnen
   276	x 2008-11-11 i  CAD  4.5 011/NSBO Umfahrung Grosshaslau: Absteckliste f?r L68 vorbereiten (Pr 1-25)
   277	x 2008-11-12 i  CAD  6.5 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 1, 3, 7 und 9 - Lagepl?ne zeichnen und plotten
   278	x 2008-11-14 i  CAD  1.5 011/NSBO Umfahrung Grosshaslau: Projektpl?ne plotten f?r H. Lang
   279	x 2008-11-17 i  CAD  0.5 011/NSBO Umfahrung Grosshaslau: Br?cke ?BB OBJ: 36.18 - Pl?ne plotten und falten
   280	x 2008-11-18 i  CAD  2.0 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 3 und 7 - ?ndern und plotten
   281	x 2008-11-19 i  CAD  3.0 011/NSBO Umfahrung Grosshaslau: Absteckliste f?r L68 und B36 vorbereiten
   282	x 2008-11-20 i  CAD  3.0 011/NSBO Umfahrung Grosshaslau: Absteckliste f?r L68 und B36 vorbereiten
   283	x 2008-11-27 i  CAD  6.0 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 3A und 5A zeichnen und Massen berechnen
   284	x 2008-11-28 i  CAD  4.0 011/NSBO Umfahrung Grosshaslau: Gel?ndeansch?ttung Ber. 3A und 5A zeichnen und Massen berechnen
   285	
   286	x 2008-11-26 i  CAD  1.0 011/NSCO Pischelsdorf - Br?cke Perschling-M?hlbach: Lageplan mit HFP zeichnen
   287	
   288	x 2008-11-27 i  CAD  1.0 011/RHKG ABA Watzmanns: Bestandsplan zeichnen (Ableitung Kl?ranlage)
   289	
   290	x 2008-11-12 i  CAD  1.0 011/RHKC ABA G?tzweis: Bestandsplan zeichnen
   291	x 2008-11-13 i  CAD  1.0 011/RHKC ABA G?tzweis: Bestandsplan zeichnen
   292	x 2008-11-14 i  CAD  1.5 011/RHKC ABA G?tzweis: Bestandsplan zeichnen
   293	x 2008-11-17 i  CAD  8.0 011/RHKC ABA G?tzweis: Bestandsplan und L?ngenschnitte zeichnen

Gruß,
Roman
 
A

Anonymous

Gast
romi1 schrieb:
Also hier einige Zeilen:

Wenn du uns jetzt noch verrätst was davon die Konstenstellen sein sollen ?

Ich gebe mal meinen Tip ab und vermute mal du willst das Ergebnis hier.
Code:
awk '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14}'  DATEI | sort -k7 -k3 -nk1
nur noch ein bischen schöner formatiert , oder :???:


robi
 
OP
R

romi1

Newbie
Hi!
Also so funktioniert es nicht; da war ich ja schon wesentlich weiter.

@robi:

lt. deinem Vorschlag erscheinen z. B. die Kostenstellen 011/NSBO an völlig unterschiedlichen Stellen, geschweige denn, dass es auch noch nach Datum sortiert wäre ...

Wenn Du bei er Option z. B. nur -k7 und nicht -k7,7 eingibst, dann zieht er nicht nur die 7. Kolonne heran, sondern ab der 7. bis zum Ende. Das gleiche gilt für die 3. Kolonne und für die 1.; tut mir leid, aber so kommt nur Mist heraus ...

Außerdem gefällt mir die Kombination (zumindest in der Form) mit awk nicht. Wie willst du wissen, das es nach $14 keine Eingabedaten mehr gibt; die geposteten Beispielzeilen sind ja nur ein kleiner Auszug .... Außerdem werden so die Quell-Zeilen verändert: wenn wo mehrere Leerzeichen sind wird nur eins draus gemacht. Ich möchte die Zeilen absolut gleich behalten, nur eben nach den angegeben Kritierien sortieren.

Wenn du uns jetzt noch verrätst was davon die Konstenstellen sein sollen ?

Bitte nicht böse sein, aber das habe ich schon ganz am Anfang verraten: Spalte 7 (z. b. 011/NSBO)

Gruß,
Roman
 

abgdf

Guru
Oh Mann, wie soll man denn erkennen, daß
Code:
x 2008-11-05 e
3 Felder sein sollen, aber
Code:
Berechnung der Aufnahme
Teil eines Feldes sein soll :?: ?

Sieh mal zu, daß Du in Deiner Datei an ein vernünftiges Feldtrennzeichen kommst , z.B. ";" oder "$" oder so. Sonst klappt das nie.

Gruß
 
OP
R

romi1

Newbie
Hi!
@abgdf: das ist leicht erklärt: bis incl. der 7. Spalte ist die Struktur quasi fix; danach kann noch eine variable Anzahl von Wörtern folgen ...
Ich werde da jetzt sicher keine neuen Spaltentrenner einführen; gibt ja so in der Form schon zig Dateien ....
Gruß,
Roman
 

abgdf

Guru
Ich werde da jetzt sicher keine neuen Spaltentrenner einführen
Nun, dann werde ich Dir da jetzt sicher nicht helfen.

(Wenn's wenigstens immer ein Leerzeichen wär' ... Es sind aber oft verschiedene Anzahlen von Leerzeichen: Das ist kaum hinzubiegen, jedenfalls nicht, wenn man nicht genau weiß, was diese Daten (z.B. "x") im einzelnen bedeuten sollen.
Auch toll sind Zeilen wie Nr. 38 oder Nr. 265: Hier weiß man überhaupt nicht mehr, wie viele Spalten da eigentlich vorhanden sein sollen ...)

Gruß

abgdf
 

Luzandro

Newbie
romi1 schrieb:
Der Grund für das Sortierproblem dürfte sein, das je Zeile vor bzw. nach den betreffende Spalten sich eine unterschiedliche Anzahl von Leerzeichen befindet.

man sort, erste Option:
-b, --ignore-leading-blanks
ignore leading blanks

außerdem noch 1. Spalte numerisch, dann sollts eigentlich passen
Code:
sort -b -k 7,7 -k 3,3 -k 1,1n test.txt

//edit: siehe unten, passt nicht ganz - nachfolgende blanks dürften nicht ignoriert werden
 

abgdf

Guru
Na gut, nun also doch.

Die "sort"-Funktion von Python ist seit Python 2.4 ziemlich mächtig. Hier also ein Skript "sortit.py":

Code:
#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-

import sre
import sys
import time

# sortit.py

arg = sys.argv

if len(arg) < 2:
    print "Usage: sortit.py file.txt"
    sys.exit()

fh = file(arg[1], "r")
a = fh.readlines()
fh.close()

def convertDate(a):

    b = a.split("-")

    c = (int(b[0]), int(b[1]), int(b[2]), 0, 0, 0, 0, 0, 0)

    return int(time.mktime(c))

r = sre.compile(" *")

c = {}

for i in a:

    i = i.rstrip("\n")

    i2 = i.strip()

    b = r.split(i2)

    if len(b) < 7:
        print i
        continue

    d = (b[6], convertDate(b[2]), b[0])

    c[d] = i

e = c.keys()
e.sort()

for i in e:
    print c[i]
Der Code dürfte nicht ganz so leicht zu verstehen sein wie sonst bei Python.

Trotzdem: HTH

Viele Grüße
 

Luzandro

Newbie
abgdf schrieb:
Die "sort"-Funktion von Python ist seit Python 2.4 ziemlich mächtig.
Warum machst dus dann so kompliziert? :p

convertTime ist unnötig
re.split/strip ebenso, dazu reicht ein simples split
das was du über dein dictionary erreichst ist im Grunde das, wofür es bei der sort-Funktion den "key"-Parameter gibt

Der Code dürfte nicht ganz so leicht zu verstehen sein wie sonst bei Python.
etwas sprechendere Namen könnten da vllt. schon mal ein wenig helfen ;)

Code:
#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-
import sys

def sortkey(line):
    cols = line.split()
    if len(cols) < 7:
        return ()
    else:
        return (cols[6],cols[2],int(cols[0]))

if len(sys.argv) < 2:
    print "Usage: sortit.py file.txt"
    sys.exit()

with open(sys.argv[1], "r") as fh:
    lines = fh.readlines()
print ''.join(sorted(lines, key=sortkey))

ACHTUNG: die Ausgabe von diesem Pythonscript (abgesehen von den oben angeführten "kosmetischen" Punkten fehlt bei abgdf die numerische Sortierung bei Spalte 1) ist NICHT ident mit dem von mir geposteten sort-Ausdruck. Die führenden blanks dürften bei diesem mit "-b" zwar ignoriert werden, allerdings scheinbar nicht die hinter der Spalte. Ich muss sagen, das Verhalten wundert mich jetzt etwas und ich sehe auf die schnelle auch keine Option um dieses zu ändern.
 
OP
R

romi1

Newbie
Hi!
@Luzandro: Endlich einmal einer, der mich versteht .... ;)

-b, --ignore-leading-blanks
ignore leading blanks

-> ja, das weiss ich und das hab ich auch (schon vor deinem Tipp) probiert, eben genau in der Form, die du angibst:

Code:
sort -b -k 7,7 -k 3,3 -k 1,1n test.txt

Aber sieh Dir mal das Ergebnis an: Z. B. wird die Kostenstelle 011/NSBO so nicht korrekt nach Datum sortiert, eben weil nach der Spalte 7 (Kostenstelle) eine unterschiedliche Anzahl von Leerzeichen ist. Was ich im sort suche, wäre eine Option in etwa in der Art: --ignore-following-blanks .... gibt es sowas? Mich interessiert nur, ob das mit sort möglich ist; Eine andere Lösung kann ich mir eh selbst auch schnitzen (z. B. mit awk); da braucht ihr euch nicht unnötig Mühe geben ...

Aber scheinbar gibt's da wirklich nichts: Zitat @Luzandro:
Die führenden blanks dürften bei diesem mit "-b" zwar ignoriert werden, allerdings scheinbar nicht die hinter der Spalte. Ich muss sagen, das Verhalten wundert mich jetzt etwas und ich sehe auf die schnelle auch keine Option um dieses zu ändern.

Und noch zu @abgdf:
Ein x am Zeilenbeginn bedeutet, daß diese Zeile in einem dem sort-Befehl folgenden awk-Programm zu verwenden ist; alle anderen Zeilen werden ignoriert (sind quasi Kommentar); ist aber für sort egel, wo es die Zeichen ohne x hinwirft, diese werden ja später sowieso ignoriert; und übrigens: bitte nicht beleidigt sein, wenn ich keine Spaltentrenner einführe. Das war nur eine Feststellung und in keiner Weise böse gemeint. Ich war nur etwas gereizt, weil ihr (robi und du) ständig nach Sachen gefragt habt, die ich sowieso schon weiter oben erklärt hatte.

Gruß,
Roman
 

Luzandro

Newbie
Nachdem ich nicht glauben konnte, dass sort damit nicht klarkommen soll, habe ich es mir jetzt nochmal angeschaut und kann dir zwar eine Lösung aber keine Begründung dazu liefern:
Code:
sort -b -k 7b,7 -k 3,3 -k 1,1n test.txt
Das verwirrende dabei ist, dass es nur funktioniert, wenn du das b an den Feldanfang der 7ten Spalte hinzufügst, aber nicht beim Feldende. Sowohl "7b,7b" als auch "7,7b" liefern ein falsches Ergebnis :???:
 
OP
R

romi1

Newbie
Hi!
Toll, @Luzandro, du hast es tatsächlich hingekriegt. Ist ja ein schönes Weihnachtsgeschenk für mich. Da muß man erst einmal draufkommen ....; aber wie Du schon sagst, ist es auch für dich etwas verwirrend, dass es so funktioniert ...

Danke jedenfalls, und Gruß,
Roman
 
Oben