Zum Inhalt wechseln


Foto

Wildcard-Match für '?' auf LFN beschränken, 8.3 ausschließen?


  • Bitte melde dich an um zu Antworten
10 Antworten in diesem Thema

#1 LigH

LigH

    Newbie

  • 45 Beiträge

 

Geschrieben 06. Februar 2017 - 12:23

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 von LigH, 06. Februar 2017 - 12:41.


#2 Damian

Damian

    Moderator

  • 9.288 Beiträge

 

Geschrieben 07. Februar 2017 - 13:57

Hallo

 

Ich habe den Beitrag in das Scripting-Forum verschoben. Passt thematisch besser hier rein. :)

 

 

Damian


www.serverhowto.de - das Howto-Projekt des MCSEboard.de

#3 LigH

LigH

    Newbie

  • 45 Beiträge

 

Geschrieben 07. Februar 2017 - 14:38

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.



#4 zahni

zahni

    Expert Member

  • 16.012 Beiträge

 

Geschrieben 07. Februar 2017 - 14:55

Geht das nicht auch mit Powershell?


Wen du nicht mit Können beeindrucken kannst, den verwirre mit Schwachsinn!


#5 LigH

LigH

    Newbie

  • 45 Beiträge

 

Geschrieben 07. Februar 2017 - 15:06

Gut möglich; damit kenne ich mich aber überhaupt nicht aus. Da ist die Syntax ja grundlegend anders als in Batch.



#6 zahni

zahni

    Expert Member

  • 16.012 Beiträge

 

Geschrieben 07. Februar 2017 - 15:31

Get-ChildItem -Path "text1_???.txt"

scheint korrekt zu funktionieren. Das DOS-Gedöns ist doch doof und umständlich.


Bearbeitet von zahni, 07. Februar 2017 - 15:32.

Wen du nicht mit Können beeindrucken kannst, den verwirre mit Schwachsinn!


#7 BOfH_666

BOfH_666

    Junior Member

  • 88 Beiträge

 

Geschrieben 07. Februar 2017 - 23:22

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 von BOfH_666, 07. Februar 2017 - 23:23.

live long and prosper!

PS:> (79,108,97,102|%{[char]$_})-join''

#8 LigH

LigH

    Newbie

  • 45 Beiträge

 

Geschrieben 08. Februar 2017 - 07:42

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...



#9 BOfH_666

BOfH_666

    Junior Member

  • 88 Beiträge

 

Geschrieben 08. Februar 2017 - 09:00

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 von BOfH_666, 08. Februar 2017 - 09:02.

live long and prosper!

PS:> (79,108,97,102|%{[char]$_})-join''

#10 LigH

LigH

    Newbie

  • 45 Beiträge

 

Geschrieben 08. Februar 2017 - 09:07

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.



#11 BOfH_666

BOfH_666

    Junior Member

  • 88 Beiträge

 

Geschrieben 08. Februar 2017 - 12:49

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.o...sing-csv-files/


live long and prosper!

PS:> (79,108,97,102|%{[char]$_})-join''