LigH 12 Geschrieben 6. Februar 2017 Melden Teilen Geschrieben 6. Februar 2017 (bearbeitet) 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? bearbeitet 6. Februar 2017 von LigH Zitieren Link zu diesem Kommentar
Damian 1.550 Geschrieben 7. Februar 2017 Melden Teilen Geschrieben 7. Februar 2017 Hallo Ich habe den Beitrag in das Scripting-Forum verschoben. Passt thematisch besser hier rein. :) Damian Zitieren Link zu diesem Kommentar
LigH 12 Geschrieben 7. Februar 2017 Autor Melden Teilen Geschrieben 7. Februar 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. Zitieren Link zu diesem Kommentar
zahni 554 Geschrieben 7. Februar 2017 Melden Teilen Geschrieben 7. Februar 2017 Geht das nicht auch mit Powershell? Zitieren Link zu diesem Kommentar
LigH 12 Geschrieben 7. Februar 2017 Autor Melden Teilen Geschrieben 7. Februar 2017 Gut möglich; damit kenne ich mich aber überhaupt nicht aus. Da ist die Syntax ja grundlegend anders als in Batch. Zitieren Link zu diesem Kommentar
zahni 554 Geschrieben 7. Februar 2017 Melden Teilen Geschrieben 7. Februar 2017 (bearbeitet) Get-ChildItem -Path "text1_???.txt" scheint korrekt zu funktionieren. Das DOS-Gedöns ist doch doof und umständlich. bearbeitet 7. Februar 2017 von zahni Zitieren Link zu diesem Kommentar
BOfH_666 577 Geschrieben 7. Februar 2017 Melden Teilen Geschrieben 7. Februar 2017 (bearbeitet) 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. bearbeitet 7. Februar 2017 von BOfH_666 Zitieren Link zu diesem Kommentar
LigH 12 Geschrieben 8. Februar 2017 Autor Melden Teilen Geschrieben 8. Februar 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... Zitieren Link zu diesem Kommentar
BOfH_666 577 Geschrieben 8. Februar 2017 Melden Teilen Geschrieben 8. Februar 2017 (bearbeitet) 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: bearbeitet 8. Februar 2017 von BOfH_666 Zitieren Link zu diesem Kommentar
LigH 12 Geschrieben 8. Februar 2017 Autor Melden Teilen Geschrieben 8. Februar 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. Zitieren Link zu diesem Kommentar
BOfH_666 577 Geschrieben 8. Februar 2017 Melden Teilen Geschrieben 8. Februar 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/ Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.