LigH 12 Posted February 6, 2017 Report Share Posted February 6, 2017 (edited) Wenn ich in einem Verzeichnis sehr viele Dateien habe (evtl. über tausend), die am Anfang ihrer Dateinamen übereinstimmen, sich aber nach etwa dem 5. Zeichen unterscheiden, dann kann ich mich nicht mehr darauf verlassen, dass für das Jokerzeichen '?' noch die Regel gilt, dass es für exakt ein Zeichen steht. Auch unter Windows nach Vista ist immer noch eine Kompatibilität für kurze Dateinamen (DOS 8.3) aktiv, die auch beim Test auf Übereinstimmung von Dateiname und Suchmuster angewendet wird. Im Ergebnis kann es dann passieren, dass man z.B. in einer FOR-Schleife versucht, einen Befehl nur auf Dateien anzuwenden, deren Dateiname einer bestimmten Länge entspricht, indem man diese Länge mit einer entsprechenden Anzahl Fragezeichen vorgibt. Wenn das System dann aber die kurzen Dateinamen zum Vergleich heranzieht, wird auch das Suchmuster auf die Länge 8.3 gekürzt, und schon erscheinen auch solche Dateien als auf das Suchmuster passend, deren langer Dateiname viel länger ist als das ursprüngliche Muster. Beispiel zum Nachstellen: @ECHO OFF ECHO Text1_Dummy1... FOR /L %%a IN (0,1,9) DO FOR /L %%b IN (0,1,9) DO FOR /L %%c IN (0,1,9) DO ECHO %%a%%b%%c > Text1_Dummy1_%%a%%b%%c.txt ECHO Text1_Dummy2... FOR /L %%a IN (0,1,9) DO FOR /L %%b IN (0,1,9) DO FOR /L %%c IN (0,1,9) DO ECHO %%a%%b%%c > Text1_Dummy2_%%a%%b%%c.txt ECHO Text1... FOR /L %%a IN (0,1,9) DO FOR /L %%b IN (0,1,9) DO FOR /L %%c IN (0,1,9) DO ECHO %%a%%b%%c > Text1_%%a%%b%%c.txt ECHO Text1_??? ECHO Text1_??? > Text1.txt FOR %%a IN (Text1_???.txt) DO ECHO %%a >> Text1.txt Ergebnis (gekürzt): Text1_??? Text1_000.txt Text1_001.txt Text1_002.txt ... Text1_997.txt Text1_998.txt Text1_999.txt Text1_Dummy1_000.txt Text1_Dummy1_001.txt Text1_Dummy1_002.txt Text1_Dummy1_003.txt Wie lässt sich das nun verhindern? Kann man dafür sorgen, dass FOR ausschließlich die langen Dateinamen auswertet? Es ist zwar möglich, das zukünftige Erzeugen von kurzen Dateinamen auf NTFS-Volumes zu verhindern: fsutil behavior set disable8dot3 1 Nach einem Neustart kann man die schon vorhandenen kurzen Dateinamen auch löschen lassen: fsutil 8dot3name strip /f /s C: Allerdings wurde (auch hier) schon über Nebenwirkungen berichtet, z.B. Inkompatibilitäten in Netzwerkfreigaben (nun ja, möglicherweise nur mit heutzutage veralteten Windows-Versionen, aber wer weiß?), und Firmware von Consumer-Mediaplayern fiele mir dazu auch noch ein – bevor ich das anwende, würde ich da schon gern mehr wissen; vielleicht gibt es ja noch andere Methoden, dafür zu sorgen, dass ich einer Dateimaske aus Sicht eines Nutzers von langen Dateinamen vertrauen kann. _ P.S.: Der Kommandozeilen-Interpreter von JPSoft (TCC, früher 4DOS / 4NT) ließ sich dahingehend konfigurieren. CMD wird so eine Möglichkeit wohl nicht bieten? Edited February 6, 2017 by LigH Quote Link to comment
Damian 1,536 Posted February 7, 2017 Report Share Posted February 7, 2017 Hallo Ich habe den Beitrag in das Scripting-Forum verschoben. Passt thematisch besser hier rein. :) Damian Quote Link to comment
LigH 12 Posted February 7, 2017 Author Report Share Posted February 7, 2017 OK, danke. Vielleicht schaffst du es auch noch, die überflüssigen Leerzeilen in den Code-Blöcken wieder zu entfernen, die jeder Bearbeitungsschritt da eingefügt hatte ... ich kann ja nun nicht mehr editieren. In der Zwischenzeit habe ich noch mehr ausprobiert. Es gab im IRC den Tipp, die FOR-Schleife auf die Ausgabe von "DIR /B" anzuwenden; da kommt aber ebenso mehr im Ergebnis heraus als erwünscht, wie wenn ich direkt mit FOR maskiere. Dies nützte also auch nichts: FOR /F "usebackq" %a IN (`DIR /B Text1_???.txt`) DO ECHO %a Zur Problemlösung verwende ich mittlerweile TCC/LE x64 (Take Command Console - Light Edition). Die wäre konfigurierbar, falls man Dateimasken nicht nur auf die LFN, sondern auch auf die SFN vergleichen wollte; Standard ist dort aber, nur die LFN zu vergleichen. Der kostenlose Funktionsumfang genügt mir. Quote Link to comment
zahni 554 Posted February 7, 2017 Report Share Posted February 7, 2017 Geht das nicht auch mit Powershell? Quote Link to comment
LigH 12 Posted February 7, 2017 Author Report Share Posted February 7, 2017 Gut möglich; damit kenne ich mich aber überhaupt nicht aus. Da ist die Syntax ja grundlegend anders als in Batch. Quote Link to comment
zahni 554 Posted February 7, 2017 Report Share Posted February 7, 2017 (edited) Get-ChildItem -Path "text1_???.txt" scheint korrekt zu funktionieren. Das DOS-Gedöns ist doch doof und umständlich. Edited February 7, 2017 by zahni Quote Link to comment
BOfH_666 577 Posted February 7, 2017 Report Share Posted February 7, 2017 (edited) Gut möglich; damit kenne ich mich aber überhaupt nicht aus. Da ist die Syntax ja grundlegend anders als in Batch. Die Syntax ist anders - das stimmt. Aber Batch wird seit Jahren nicht mehr weiterentwickelt - und das aus gutem Grund. ;) Mit Powershell wäre Dein Problem keins. Wenn Du noch eine Weile in der Windows-Adminsitration unterwegs sein möchtest, würde sich die Kenntnis von Powershell auf lange Sicht für Dich mit ziemlich großer Sicherheit auszahlen. :thumb1: ... und Hilfe bekommst Du für Powershell auch schneller und vielfältiger. Edited February 7, 2017 by BOfH_666 Quote Link to comment
LigH 12 Posted February 8, 2017 Author Report Share Posted February 8, 2017 Wie sähe denn dann vergleichsweise ein Einzeiler für PowerShell aus, mit dem man alle vorhandenen Dateien nach dem Muster Text1_???.txt in Text1_Dummy3_???.txt mal eben schnell an der Kommandozeile umbenennen kann? So ein Beispiel würde mir sicherlich reichlich Syntax-Elemente liefern, nach denen ich dann weiter suchen kann. Und nein, das ist bei weitem nicht die einzige Aufgabe, die ich auf solche Art von Dateigruppen anwenden will, und die unterscheiden sich immer wieder... Quote Link to comment
BOfH_666 577 Posted February 8, 2017 Report Share Posted February 8, 2017 (edited) Get-ChildItem -Path 'Verzeichnispfad zu Deinen Dateien' -Filter 'Text1_*.txt' | Where-Object -Property BaseName -Value 'Text1_(\d{3})$' -Match | Foreach-Object -Process {Rename-Item -Path $_.FullName -NewName "Text1_Dummy3$($Matches[1]).txt"} Wie fast immer bei Powershell, gibt es natürlich mehrere Lösungen, die ans Ziel führen. Eine könnte diese sein. Ich bin davon ausgegangen, dass die Dateinamen 3 aufeinanderfolgende Zahlen enthalten. Wenn es drei beliebige zeichen sind, müsstest Du noch das Match-Pattern anpassen. Achja ... wenn Du unbedingt einen Einzeiler brauchst, kannst Du die Zeilenumbrüche nach den Pipes ("|") entfernen - so isses aber besser lesbar. ;) :thumb1: Edited February 8, 2017 by BOfH_666 Quote Link to comment
LigH 12 Posted February 8, 2017 Author Report Share Posted February 8, 2017 Ja, danke, lesbar und auch irgendwie gleich vom Sinn und Zweck her verständlich. Sehr deskriptive Befehle, erinnert fast etwas an SQL-JOINs mit GROUPs, von Umfang und Struktur her. Auf jeden Fall reichlich Schlagworte zum Stöbern. Quote Link to comment
BOfH_666 577 Posted February 8, 2017 Report Share Posted February 8, 2017 Wenn die englische Sprache keine zu große Hürde für Dich darstellt und Du gern tiefer einsteigen möchtest, hast Du hier mal ein paar Starthilfen .... https://powershell.org/forums/topic/using-csv-files/ Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.