sg3105
Goto Top

Alphanumerische Ausgabe maskierter Dateien in FOR-Schleife

Eine FOR-Schleife soll alle passenden Dateien alphanumerisch sortiert ausgeben.

Die folgende Zeile ist schuld:
FOR %%F in (*.ext) DO TYPE %%F>>%allfiles%
Die Dateinamen können ja nichts dafür, daß sie numerische Anteile enthalten.
Die FOR-Schleife gibt die Dateien in der folgenden Reihenfolge raus:
file_1.extfile_10.extfile_11.extfile_12.extfile_13.extfile_14.extfile_15.extfile_16.extfile_17.extfile_18.extfile_19.extfile_2.extfile_20.extfile_21.extfile_22.extfile_3.extfile_4.extfile_5.extfile_6.extfile_7.extfile_8.extfile_9.ext
Benötigt wird aber eine alphanumerische Sortierung:
file_1.extfile_2.extfile_3.extfile_4.extfile_5.extfile_6.extfile_7.extfile_8.extfile_9.extfile_10.extfile_11.extfile_12.extfile_13.extfile_14.extfile_15.extfile_16.extfile_17.extfile_18.extfile_19.extfile_20.extfile_21.extfile_22.ext
Die Dateinamen und die darin enthaltenen Zahlen sind unbekannt, so daß eine echte alphanumerische Sortierung erfolgen muß.
Geht das irgendwie oder muß ich an Microsoft schreiben?

Content-Key: 128414

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

Ausgedruckt am: 28.03.2024 um 18:03 Uhr

Mitglied: rubberman
rubberman 01.11.2009 um 22:49:41 Uhr
Goto Top
Ebenfalls ohne Begrüßung.

Die Sortierung ist alphanumerisch. Was du willst ist: Handelt es sich um einen Text-Teilstring des Dateinamens, dann behandle ihn alphanumerisch, ansonsten numerisch. Die Datei kann nix für ihren numerischen Namensanteil, aber der Programmierer der statt 01 nur 1 verwendet.

Nochmal ohne Gruß.
Mitglied: SG3105
SG3105 02.11.2009 um 09:07:11 Uhr
Goto Top
Danke für die Antwort.
Ich will hier nicht um Wortbezeichnungen streiten, mir geht es um eine Lösung des Problems.
Der Programmierer bin ich und ich muß mich an die Namesgebung halten und die ist nunmal nicht 0# oder 00# etc.
Viele Grüße an Alle, die mir weiterhelfen können.
Mitglied: Biber
Biber 02.11.2009, aktualisiert am 18.10.2012 um 18:39:51 Uhr
Goto Top
Auch ohne Begrüßung.

Die Sortierung ist alphanumerisch.
Wenn du dich als Programmierer fühlst, solltest du die Anforderungen im Pflichtenheft gegebenfalls beim Auftraggeber in Frage stellen und nicht hier.

Wenn du unter dem CMD eine "logisch numerisch aufsteigende" Sortierung willst, dann muttu das selber machen.
Denn es existiert kein Gegenstück zu dem Explorer-Registrykey "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoStrCmpLogical" - der ist ein reines GUI-Schmankerl (siehe auch hier im Archiv ).

Workaround (Demo am CMD-Prompt)
FOR /L %i in (1,1,111) DO IF Exist "D:\einpfad\file_%i.ext" TYPE "D:\einpfad\file_%i.ext">>%allfiles%

Das mag ich, solche Beiträge am Montag Morgen.
Mitglied: SG3105
SG3105 02.11.2009, aktualisiert am 18.10.2012 um 18:39:51 Uhr
Goto Top
Zitat von @Biber:
Wenn du dich als Programmierer fühlst, solltest du die
Anforderungen im Pflichtenheft gegebenfalls beim Auftraggeber in Frage
stellen und nicht hier.
Gut, dann muß ich mal mit mir reden:
...
Der Auftraggeber meint:
"Um es mal mit einigen Beispielen zu sagen:
Bei Autos: Haudi H8, nicht 08 (Keine Werbung, da Herstellername und Typ geändert).
Bei Hausnummern: 13, nicht 013,
Bei Straßenbahnen oder Buslinien: Linie 7, nicht Linie 07
Nur manche Geheimagenten nennen sich 007."

Wenn du unter dem CMD eine "logisch numerisch aufsteigende"
Sortierung willst, dann muttu das selber machen.
Logisch sind beide Sortierreihenfolgen.
Ich brauche aber nunmal die (von mir aus) "numerisch" richtige.

Denn es existiert kein Gegenstück zu dem Explorer-Registrykey
"HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoStrCmpLogical"
- der ist ein reines GUI-Schmankerl (siehe auch
im Archiv
Es fehlt das Leerzeichen hinter dem Link, besser so:
Sortierung von Dateinamen mit Dezimalwerten in Windows Explorer
FOR /L %i in (1,1,111) DO IF Exist
> "D:\einpfad\file_%i.ext" TYPE
> "D:\einpfad\file_%i.ext">>%allfiles%
> 
Das löst leider nur einen Einzelfall.
Demnach müßte wohl hier im Forum eine Option "derzeit nicht lösbar" hinzugefügt werden.
Bitte nicht gleich wieder sauer werden.

Geht sowas vielleicht mit anderen Onboard-Mitteln (vbs?)?
Ich kenn mich da nicht aus - sonst würde ich ja hier auch nicht soviel fragen.

Das mag ich, solche Beiträge am Montag Morgen.
Ist das jetzt ironisch gemeint?

Grüße.
Mitglied: Biber
Biber 02.11.2009, aktualisiert am 18.10.2012 um 18:39:51 Uhr
Goto Top
Zitat von @SG3105:
Der Auftraggeber meint:
"Um es mal mit einigen Beispielen zu sagen:
Bei Autos: Haudi H8, nicht 08 (Keine Werbung, da Herstellername und Typ geändert).
Bei Hausnummern: 13, nicht 013, Bei Straßenbahnen oder Buslinien: Linie 7, nicht Linie 07
Nur manche Geheimagenten nennen sich 007."

Na ja, mit der Aussage lässt sich ja schon etwas anfangen

Es fehlt das Leerzeichen hinter dem Link, besser so: Sortierung von Dateinamen mit Dezimalwerten in Windows Explorer

Jepp. Sorry für das fehlende Leerzeichen. Ist oben korrigiert.

FOR /L %i in (1,1,111) DO IF Exist "D:\einpfad\file_%i.ext" TYPE "D:\einpfad\file_%i.ext">>%allfiles%
Das löst leider nur einen Einzelfall.
Sonst würde es ja auch nicht Individual-Programmierung heißen, sondern Pauschal-Programmierung.
Bzw. du müsstest nicht in einem Forum nachfragen, sondern könntest bei Bertelsmann nachschlagen.

Demnach müßte wohl hier im Forum eine Option "derzeit nicht lösbar" hinzugefügt werden.
Ich finde es schon immer entgegenkommend von mir, wenn ich Beiträge als "temporär nicht löschbar" noch ein paar Stunden stehen lasse. face-wink
Bitte nicht gleich wieder sauer werden.
Dito *g
Geht sowas vielleicht mit anderen Onboard-Mitteln (vbs?)?
Sagen wir so... mit VBS sicherlich schneller als mit Batch -- FALLS das ein Kriterium ist.

Wir können es doch aber so oder so nur mit einem (Batch- oder VBS- oder PERL oder Whatever-)Algorithmus einfangen, wenn wir diese Regeln verbal beschreiben können.
Wie Du es oben jetzt getan hast.
Wenn es keine Ausnahmen von der Regel gibt, dass alle Dateinamen, die Ziffern im Dateinamen enthalten "numerisch aufsteigend" statt "alphanumerisch" sortiert werden sollen?

Nochmal kompakt meine Rückfragen:
  • gibt es Ausnahmen von der Sortierregel "numerisch aufsteigend"?
  • wie ist denn der Umfang/die Häufigkeit, in der ihr dieses "Type-mir-alles-in-einen-Monstertext" macht? 20000 Dateien und das 3x täglich? Oder 15 Dateien einmal im Monat?


Ist das jetzt ironisch gemeint?
Keine Ahnung, was Ironik sein mag - ich bin da eher sachlich und nordisch-unterkühlt.
Grüße.
Jepp.
Mitglied: 76109
76109 02.11.2009 um 15:24:00 Uhr
Goto Top
Hallo zusammen!

Nachdem jetzt bereits Montagnachmittag ist und sich die Gemüter hoffentlich wieder beruhigt haben, hier ein VB-Script (*.vbs)face-smile

Das Script liest Dateinamen aus einem Verzeichnis ein und schreibt die Dateinamen numerisch sortiert in die Datei Sort.Txt

Bei diesem Script, wird angenommen, dass - wie im Beispiel - ein Delimiter ("_") vorhanden ist. Wenn nicht, muss der Code entsprechend angepasst werden.

Konstanten entsprechend anpassen:
 
Const Ordner = "X:\Test"			'Verzeichnis  
Const Ausgabe = "X:\Test\Sort.Txt"		'Numerisch sortierte Ausgabedatei  

Const Delim = "_"				'Trennzeichen  
Const Extension = ".ext"			'Dateierweiterung  

Const adVarChar = 200 			'Konstanten ADO-Recordset                   
Const adFldIsNullable = 32

Dim Fso, Rec, File, Text, SortName

'Main Beg  
    
    Set Fso = CreateObject("Scripting.FileSystemObject")  
    
    Call OpenRecordset
    
    For Each File In Fso.GetFolder(Ordner).Files
        If LCase(Right(File.Name, 4)) = LCase(Extension) Then
            SortName = Right("00000" & Split(Fso.GetBaseName(File.Name), Delim)(1), 6)  
            Call WriteRecordset(File.Name, SortName)
        End If
    Next
        
    Set File = Fso.CreateTextFile(Ausgabe)
        
    With Rec
        .Sort = "Alias"  
        .MoveFirst
         Do Until .EOF
             Text = .Fields(0)
             File.WriteLine Text
            .MoveNext
         Loop
    End With
    
    Rec.Close:  File.Close

'Main End  

Private Sub OpenRecordset()
    Set Rec = CreateObject("ADOR.Recordset")  
    With Rec.Fields
        .Append "Name", adVarChar, 64, adFldIsNullable  
        .Append "Alias", adVarChar, 16, adFldIsNullable  
         Rec.Open
    End With
End Sub

Private Sub WriteRecordset(ByRef File, ByRef Alias)
    With Rec
        .AddNew
        .Fields("Name") = File  
        .Fields("Alias") = Alias  
        .Update
    End With
End Sub

Gruß Dieter
Mitglied: SG3105
SG3105 02.11.2009 um 17:14:35 Uhr
Goto Top
Ironik ist gut - gefällt mir. face-smile
Also bleiben wir sachlich fachlich, nur unterkühlt und regnerisch ist mir derzeit etwas unangenehm (Sauwetter).

Umfang/Häufigkeit:
Also mal etwas zum Hintergrund:
Ich habe gezählt (zählen lassen): Derzeit handelt es sich insgesamt um 8610 Dateien in diversen Unterverzeichnissen gegliedert. Jede Datei definiert ein Symbol, ein Gehäuse oder ein Bauteil (Symbol und Gehäuse-Verknüfung) als Bibliotheks-Element für ein Schaltplan und Layoutprogramm. Aus diesem sich ständig erweiternden Fundus werden über Batchdateien jeweils Bibliotheken in Textform erstellt, die dann von dem Programm eingelesen werden können. Dabei können einzelne Bibliotheks-Elemente in mehreren Bibliotheken vorkommen. Daraus resultiert auch ein wesentlicher Vorteil: Wird ein einziges Element geändert kann durch Suchen ermittelt werden welche Bibliotheken betroffen sind, die dann neu erstellt und eingelesen werden. Damit erhalte ich IMMER bibliotheksübergreifende Konsistenz!
Das Ganze muß also LANGLEBIG sein und wird durchschnittlich vielleicht 10 mal monatlich benötigt. Wenn's gebraucht wird eher so 30 mal am Stück innerhalb weniger Tage.
Geschwindigkeit ist kein wichtiges Kriterium.

gibt es Ausnahmen von der Sortierregel "numerisch aufsteigend"?
Wenn ich in die Zukunft blicken könnte...

Ausnahmen(?): Es gibt keine feste Dateinamensstruktur. Das Eingangsbeispiel war eben nur ein Beispiel.
Zum Verständnis: Generell gibt es keine Einschränkung bei der Namensvergabe. Diese legt ja der jeweilige Hersteller fest. Ergo kann ein Name und damit auch der Dateiname an jeder und an mehreren (min. zwei, besser drei) Stellen einen numerischen Anteil haben. Zusätzlich braucht man ein paar Sonderzeichen zur Trennung von Blöcken. Wie die Sonderzeichen einsortiert werden ist unerheblich, solange gleiche immer beieinander landen.
Folgende Zeichen im (Datei-)Namen habe ich bisher verwenden müssen: "a-zA-Z0-9µ,.+-_~!°"
Verbotene Zeichen: Leerzeichen und Semikolon, Hochkomma.
Alle für Dateinamen problematische Zeichen "*?/\" etc. kommen im Dateinamen nicht vor.

Ürigens spricht das Programm von "alphanumerisch sortiert" - daher mein "Sprachfehler".

Grüße.
Mitglied: SG3105
SG3105 02.11.2009 um 17:23:15 Uhr
Goto Top
Das war jetzt etwas zu schnell und zu sehr an obigem Beispiel orientiert.
Trotzdem Danke!

Das Trennzeichen ist leider so nicht vorhanden.
Genauere Infos zur Namensstruktur siehe oben.

Wie kann/muß ich das VBS aufrufen bzw. von der Batch starten?
Oben genannte FOR-Schleife raus und "Name.vbs" als Einzeiler rein?
Kann man Verzeichnis und Ausgabedatei als Parameter übergeben?

Gibt's eine Anleitung für VBS-DAUs wie mich?

Gruß.
Mitglied: miniversum
miniversum 02.11.2009 um 18:30:52 Uhr
Goto Top
Werden die Dateien den auch in der Reihnenfolge der Sortierungen erstellt?
Wenn ja warum dan nicht einfach so?:
dir /b /OD *.ext >%allfiles%
Mitglied: rubberman
rubberman 03.11.2009 um 02:11:24 Uhr
Goto Top
Hallo SG3105,

hab selten solche Verrenkungen gemacht. Schau mal ob das zum Ergebnis führt:
@echo off &setlocal

set extension=ext

type nul>%temp%\temp.txt
set "num=1234567890"  
for %%i in (*.%extension%) do set "datei=%%i" &set "name=%%~ni" &call :sub  
sort %temp%\temp.txt /o %temp%\temp.txt

:: hier deine TYPE-Umleitung, statt ECHO
for /f "delims=; tokens=2" %%i in (%temp%\temp.txt) do echo "%%i"  

del %temp%\temp.txt
pause
goto :eof


:sub
echo %name:~,1%|findstr "[0-9]">nul&&set "startnumeric=1"  
set "text=%name%"  
set "zahl=%name%"  
set /a nt=1
:loop1
for /f "delims=%num% tokens=1*" %%a in ("%text%") do set "tpart%nt%=%%a" &set "text=%%b"  
if not defined tpart%nt% goto weiter1
set /a nt+=1
if defined text goto loop1
:weiter1
set /a nt-=1
for /l %%n in (1,1,%nt%) do call set "alltext=%%alltext%%%%tpart%%n%%"  

set /a nn=1
:loop2
for /f "delims=%alltext% tokens=1*" %%a in ("%zahl%") do set "npart%nn%=%%a" &set "zahl=%%b"  
if not defined npart%nn% goto weiter2
set /a nn+=1
if defined zahl goto loop2
:weiter2
set /a nn-=1
for /l %%x in (1,1,%nn%) do (
  call set npart%%x=0000000%%npart%%x%%
  call set npart%%x=%%npart%%x:~-8%%
)
set /a nparts=nt+nn
set /a xt=0
set /a xn=0
set /a x=0
if not defined startnumeric goto loop3
set /a xn+=1
set /a x+=1
call set "string=%%npart%xn%%%"  
:loop3
if %x%==%nparts% goto weiter3
set /a xt+=1
set /a x+=1
call set "string=%%string%%%%tpart%xt%%%"  
if %x%==%nparts% goto weiter3
set /a xn+=1
set /a x+=1
call set "string=%%string%%%%npart%xn%%%"  
goto loop3
:weiter3
set "string=%string%                                                                                                   "  
set "string=%string:~,100%;%datei%"  
>>%temp%\temp.txt echo %string%
set "startnumeric="  
set "alltext="  
set "tpart1="  
set "npart1="  
set "string="  
goto :eof

Grüße
rubberman
Mitglied: 76109
76109 03.11.2009 um 09:43:25 Uhr
Goto Top
Hallo SG3105!

Zitat von @SG3105:
Ergo kann ein Name und damit auch der Dateiname an jeder und an mehreren (min. zwei, besser drei) Stellen einen numerischen Anteil haben.
Gleich an mehreren Stellen numerischen Anteil? Nö danke, da weiß ich doch besseres mit meiner Zeit anzufangenface-wink

Gruß Dieter