ralfpl18
Goto Top

Batch-Datei für Sortierung sortiert Zahlen größer 99 falsch

Hallo Profis face-smile

Ich bin neu hier im Forum und hoffe, ich poste mein Anliegen an der richtigen Stelle. Ich wäre Euch sehr dankbar für einen Hinweis oder die Lösung zu folgendem Problem:

Ich möchte eine Textdatei per batch so sortieren, dass die erste Spalte die Zahlen in aufsteigender Reihenfolge sortiert. Hier ist der beispielhafte Inhalt dieser Textdatei sortieren.txt:

10; LDG; 10; 1234;
20; TDG; 20; 5678;
40; TDG; 40; 13141516;
50; TDG; 50; 17181920;
15; LDG; 15; 9101112;
16; LDG; 16; 9191112;
45; TDG; 45; 9101112;
100; LDG; 100; 9101112;

Dazu habe ich folgende Batch-Datei sortieren.bat (Auszug, denn da sind noch weitere Funktionen drin):
...
type nul>aaaaa.txt
for /f "tokens=1-4 delims=;" %%a in ('(for /f "tokens=1-4" %%e in (C:\test\sortieren.txt^) do @echo %%e %%f %%g %%h^)^|sort') do echo %%a; %%b; %%c; %%d; >>C:\test\aaaaa.txt
...

Das funktioniert bestens, wenn ich in der ersten Spalte keine Zahlen größer 99 habe. Aus der oberen Datei, wo die erste Spalte eine 100 hat, sortiert er mir momentan das hier in aaaaa.txt:

10;LDG;10;1234;
100;LDG;100;9101112;
15;LDG;15;9101112;
16;LDG;16;9191112;
20;TDG;20;5678;
40;TDG;40;13141516;
45;TDG;45;9101112;
50;TDG;50;17181920;

Was könnte dafür die Ursache sein bzw. wie bekomme ich das Problem gelöst, dass er die Hunderter korrekt einsortiert?
Ich kann es mir einfach nicht erklären, bin allerdings auch noch kein Batch-Profi, sondern erst Anfänger.
Ich bedanke mich schon mal vorweg für hilfreiche Antworten. face-smile

Beste Grüße,
Ralf

Content-Key: 392878

Url: https://administrator.de/contentid/392878

Ausgedruckt am: 29.03.2024 um 09:03 Uhr

Mitglied: 137846
Lösung 137846 15.11.2018 aktualisiert um 09:30:26 Uhr
Goto Top
Was könnte dafür die Ursache sein bzw. wie bekomme ich das Problem gelöst, dass er die Hunderter korrekt einsortiert?
Genügend Nullen voranstellen und von hinten passend die Zahl inkl evt. Nullen extrahieren. Hier z.B. immer 4 Stellen von rechts.
set "num=00099"  
set "numforsort=%num:~-4%"  

A.
Mitglied: erikro
Lösung erikro 15.11.2018 um 11:02:17 Uhr
Goto Top
Moin,

Zitat von @RalfPL18:
Was könnte dafür die Ursache sein bzw. wie bekomme ich das Problem gelöst, dass er die Hunderter korrekt einsortiert?

Die Ursache heißt alphanumerische Sortierung. Im Unterschied zur numerischen Sortierung wird bei der alphanumerischen nicht nach dem Wert der Zahl, sondern nach dem Wert des ersten Zeichens sortiert. Wenn das nicht eindeutig ist, dann nach dem Wert des zweiten usw. Hast Du also

Alfred
Hans
Anne
Bruno
Berta

kommt heraus

Alfred
Anne
Berta
Bruno

Bei Zahlen ist es dann genauso. Sortierst Du alphanumerisch, dann kommt bei

1
10
11
100
101

erwartungsgemäß das heraus:

1
10
100
101
11

Lösung: wie schon @137846 schrieb führende Nullen.

hth

Erik
Mitglied: RalfPL18
RalfPL18 15.11.2018 aktualisiert um 22:17:55 Uhr
Goto Top
@137846 und @erikro: Vielen Dank für Eure Hinweise. Ich habe diese wie folgt umgesetzt, allerdings gibt es noch ein abschließendes Problem am Schluss:

setlocal enabledelayedexpansion

for /f "tokens=1-4 delims=;" %%a in (c:\test\sortieren.txt) do echo 0%%a; %%b; %%c; %%d; >>c:\test\sortieren_pruefprozedur\a.txt

set A=c:\test\sortieren_pruefprozedur\a.txt
set B=c:\test\sortieren_pruefprozedur\b.txt

for /f "usebackq delims=;" %%i in ("%A%") do (
set "Zeile=%%i"
"%B%" echo !Zeile:~-3%!)

In a.txt schreibt er mir wie gewünscht:

010; LDG; 10; 1234;
020; TDG; 20; 5678;
040; TDG; 40; 13141516;
050; TDG; 50; 17181920;
015; LDG; 15; 9101112;
016; LDG; 16; 9191112;
045; TDG; 45; 9101112;
0100; LDG; 100; 9101112;

Ich habe jetzt eine führende Null.

In b.txt schreibt er mir die erste Spalte wie gewünscht:

010
020
040
050
015
016
045
100

Nur...

==> Wie bekomme ich in b.txt die restlichen Spalten wieder dazu? Es wird nur die erste Spalte in b.txt ausgegeben und was ich auch probiere, ich bekomme die anderen drei Spalten einfach nicht angefügt. <==
Mitglied: 77559
Lösung 77559 16.11.2018, aktualisiert am 21.11.2018 um 01:32:08 Uhr
Goto Top
In PowerShell gibt es zwar das gleiche Problem,
aber dafür eine sehr schöne Lösung.

Hierbei wird on the fly ein (virtueller) Sortierschlüssel gebildet der alle Zahlen auf eine einheitliche Länge bringt (links mit Leerzeichen aufgefüllt) so das das alphabetische Sortieren wieder korrekte Werte ergibt.

:: Q:\Test\2018\11\16\AD_392878.cmd
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
Set "INP=.\sortieren.txt"  
Set "OUT=.\sortiert.txt"  

:: um überschaubare Zeilenlängen zu erhalten wird der Befehl aus Variablen erstellt.
Set "$TO=$ToNatural={[regex]::Replace($_,'\d+',{ $args.Value.PadLeft(20)})}"  
powershell -NoP -C "%$TO%;Get-Content '%INP%'|Sort-Object $ToNatural|Set-Content '%OUT%'"  
type "%OUT%"  

Ausgabe

> AD_392878.cmd
10; LDG; 10; 1234;
15; LDG; 15; 9101112;
16; LDG; 16; 9191112;
20; TDG; 20; 5678;
40; TDG; 40; 13141516;
45; TDG; 45; 9101112;
50; TDG; 50; 17181920;
100; LDG; 100; 9101112;
Mitglied: RalfPL18
RalfPL18 18.11.2018 um 10:27:27 Uhr
Goto Top
Hallo LotPings,

zum Wochenende komme ich endlich dazu, den Script zu testen und was soll ich sagen: Ich bin begeistert, wie schön das funktioniert! Ganz großes Dankeschön an Dich!

Eine tolle Sache mit Powershell und den Befehlsabfolgen in der Pipe, die "on the fly" pro Zeile abgearbeitet werden.
Ich werde heute mal in die Syntax abtauchen, um die Logik der Variablendeklarationen und Befehlsfolgen richtig zu erfassen. Zum Glück gibt es Internet und u.a. ein so tolles Forum / so tolle Leute wie hier in www.administrator.de .

Beste (Wochenend)Grüße,
Ralf


Zitat von @77559:

In PowerShell gibt es zwar das gleiche Problem,
aber dafür eine sehr schöne Lösung.

Hierbei wird on the fly ein (virtueller) Sortierschlüssel gebildet der alle Zahlen auf eine einheitliche Länge bringt (links mit Leerzeichen aufgefüllt) so das das alphabetische Sortieren wieder korrekte Werte ergibt.

> :: Q:\Test\2018ß11\16\AD_392878.cmd
> @Echo off&SetLocal EnableExtensions EnableDelayedExpansion
> Set "INP=.\sortieren.txt"  
> Set "OUT=.\sortiert.txt"  
> 
> :: um überschaubare Zeilenlängen zu erhalten wird der Befehl aus Variablen erstellt.
> Set "$TO=$ToNatural={[regex]::Replace($_,'\d+',{ $args.Value.PadLeft(20)})}"  
> powershell -NoP -C "%$TO%;Get-Content '%INP%'|Sort-Object $ToNatural|Set-Content '%OUT%'"  
> type "%OUT%"  
> 

Ausgabe

>> AD_392878.cmd
> 10; LDG; 10; 1234;
> 15; LDG; 15; 9101112;
> 16; LDG; 16; 9191112;
> 20; TDG; 20; 5678;
> 40; TDG; 40; 13141516;
> 45; TDG; 45; 9101112;
> 50; TDG; 50; 17181920;
> 100; LDG; 100; 9101112;
>