Verständsnisproblem bei Batch/CMD Code

Suma

Lt. Commander
Registriert
Juni 2013
Beiträge
1.528
Hey,

folgende Situation:

ich hab auf der Arbeit 650 Dateien, die Sonderzeichen im Namen haben, die sie aber nicht enthalten dürfen, weil das Tool, in das sie eingelesen werden, diese Sonderzeichen nicht zulässt (& oder # beispielsweise).

Ein Tool dafür zu verwenden ist ausgeschlossen, ich muss es mit normalen Windowsmitteln hinbekommen!

Nun habe ich folgenden Code im Internet gefunden, mit dem man Dateinamen suchen und ersetzen kann:

Code:
for %i in ("e:\schnipsel\*+*.*") do @set "x=%~nxi" & @echo ren "%i" "!x: + =_!"
(Quelle: http://www.administrator.de/frage/pluszeichen-dateinamen-finden-ersetzen-132168.html)

Ich versuche seit gestern Abend diese (an sich bestimmt simple) Zeile Code zu verstehen... Leider ohne Erfolg.

"for %i ("e:\schnipsel\*+*.*")" ist an sich klar: Für jedes Item (Datei) in Verzeichnis blabla...

"+" bedeutet, mindestens ein beliebiger character und "." beliebige character, richtig? (reguläre Ausdrücke oder wie heißt das noch? Einzige Frage: würde das "+" alleine nicht reichen, weil es ja auch beliebig? oder steht das "+" für das zu ersetzende Zeichen und "." für die anderen Zeichen im Dateinamen?)

do ist ebenfalls klar, aber alles danach ist Bahnhof...

Kann mir jemand kurz die Syntax und die einzelnen Bestandteile erläutern, sodass ich den Code für mein Problem adaptieren kann?

P.S: Falls ihr noch eine einfachere Möglichkeit kennt, immer her damit ;)

LG, Suma
 
Nein
Pluszeichen bedeutet + genauso wie ein Punkt . bedeutet
die commandline kann kein regex sondern nur simple wildcards
also
'*' beliebige Anzahl von zeichen
'?' EIN beliebiges Zeichen
alles ander sind die Zeichen selbst

Bsp.: *+*.* match zum Beispiel
abc+abc.x
+abc.txt
abc+.txt

wenn du das verwenden willst müsstest schreiben
*&*.* und dann nohcmal *#*.* (in einer Zeile geht das mit Windows bordmitteln nicht)
 
Okay, danke

Ich habe mir schon gedacht, dass ich für jedes Sonderzeichen eine eigene Codezeile brauche, okay...

Bedeutet, das Zeichen vor dem "." ist immer mein Sonderzeichen, das ich ersetzen möchte! Soweit verstanden
 
Ja, in diesem fall schon

wobei natürlich in der extension kein sonderzeichen ersetzt wird
Bsp..
*#*.*
match z.B.
abc#abc.xyz#xyz

wenn du aber sowieso nur im vorderen Teil des Namens ein sonderzeichen hast, ist es egal..
eigentlich müsste sogar *#* reichen. hab es jetzt aber nicht ausprobiert

wenn du mehr Funktionalität brauchst, gibts dafür "FINDSTR" , das kann auch mit Regex umgehen, damit kenn ich mich aber nicht wirklich gut aus


Edit:
Wenn du windows 7 oder neuer installiert hast, gibts da auch die Powershell, die ist viel mächtiger als die "normale" commandline, damit kannst auch viel mehr machen
 
Zuletzt bearbeitet: (verweis auf powershell)
Also Java(script) fällt weg, weil ich das nicht kann ;)

der Codeschnipsel sieht so einfach aus, da würde ich gerne dran festhalten, wenn das geht...

Ich habe den Code in cmd ausgeführt und folgendes ist passiert:

er findet meine testdateien, aber nur in der obersten Ebene der Ordnerstruktur. Jedoch tut er nichts damit, er zeigt sie mir nur an.

Ich würde mal vermuten, dass der Code noch einen Fehler hat, da folgendes am Ende jeder Zeile steht: "!x: # =n!"

ren "C:\Users\***\Desktop\Test\#das.docx" "!x: # =n!"
ren "C:\Users\***\Desktop\Test\das#das.docx" "!x: # =n!"
ren "C:\Users\***\Desktop\Test\dasd#.docx" "!x: # =n!"
 
Momentan zeigt der Code auch nur etwas an weil da noch ein "echo" drin steht. Ist aber zum entwickeln erst mal ok, dann siehst du welche Befehle er später ausführen würde wenn du das echo entfernst.

ren "C:\Users\***\Desktop\Test\#das.docx" "!x: # =n!"

Das kommt mir aber auch seltsam vor, vor allem wenn ich mal die Hilfe zu ren suche, dann finde ich von der Syntax nichts. Der ren Befehl kann keine solche Syntax mit der man zeichen entfernen könnte. Wenn dann müsste das schon die CMD liefern, was aktuell nicht zu passieren scheint.

probier mal folgenden Befehl (Aktivierung der verzögerten Variablenauswertung, das aktiviert erst den ! Befehl):

Code:
cmd /v:on

und dann das Skript noch ein mal.
 
Vielen Dank,

jetzt bin ich schon einen guten Schritt weiter!

for %i in ("C:\Users\***\Desktop\Test\*#*.*") do @set "x=%~nxi" & @echo ren "%i" "!x:#=n!"

ren "C:\Users\***\Desktop\Test\#das.docx" "ndas.docx"
ren "C:\Users\***\Desktop\Test\das#das.docx" "dasndas.docx"
ren "C:\Users\***\Desktop\Test\dasd#.docx" "dasdn.docx"

Er ersetzt mir nun # durch mein n!

Aber wie du richtig vermutet hast, er gibt mir das nur aus, noch verändert er nichts!

P.S: Kann ich das noch ausweiten auf Ordner und Unterordner? (Meine 650 Dateien sind auf über 1000 Ordner und insgesamt über 5000 Dateien verteilt.)
 
Zuletzt bearbeitet:
Ok:

"!x:#=n!" heißt: ersetze # durch n, wenn du was anderes haben willst tausch das n einfach aus


for /r %i in ("C:\Users\***\Desktop\Test\*#*.*") do @set "x=%~nxi" & @echo ren "%i" "!x:#=n!"

Mit dem /r sollte er rekursiv durch die Unterordner gehen (erst mal testen). Danach den hervorgehobenen Echo-Teil rausnehmen, dann führt er es aus.
 
Hey,

wenn ich das "/r" davorsetze, werkelt er eine Weile (länger als vorher) aber tut gar nichts und gibt mir auch nichts aus.
 
Die Syntax für rekursive Programmierung scheint etwas anders zu sein:

FOR /R [[drive:]path] %%parameter IN (set) DO command

Wo ist jetzt der Unterschied zwischen [[drive.]path] und dem (set) wo vorher immer mein Ordner stand?
 
Das erste ist nur der Pfad, das Set ist wohl das Namenspattern der Files. So interpretier ich das zumindest (mit den File-Suchmustern hab ich bei FOR bisher wenig gemacht, ich hab damit immer nur Textzeilen zerlegt)
 
Irgendwie möchte er meine Console nicht mehr kopieren...

Kann das Ergebnis jetzt nicht posten... Aber es funktioniert auf jeden Fall!

Okay, nächster Schritt:

Ordner und Unterordner umbennen!

Wenn ich einfach meinen bisherigen Code (nicht rekursiv) um ein /D erweitere, nimmt er statt Dateien Ordner...

Nur die Kombination zwischen /R und /D gefällt cmd gar nicht... Egal in welcher Schreibweise, ob rekursiv oder nicht...
Ergänzung ()

Ha!

geschafft!

for /R "C:\Users\***\Desktop\Test\" /D %i in ("*#*.*") do @set "x=%~nxi" & @echo ren "%i" "!x:#=n!"

Damit macht er auch Ordner und Unterordner!

Vielen Dank für eure Hilfe! Ihr habt mich gerettet!

Big Thx!

LG, Suma
Ergänzung ()

Habe nochmal ohne "@echo" probiert und er verändert die Ordner jetzt auch richtig!

Thx!
 
In cmd zu arbeiten macht mir mehr Spaß als irgendwas richtig zu programmieren.... (Da ich nicht programmieren kann, ist cmd mein Freund und Helfer ;) )
 
Mit n bissl programmieren kann man halt vieles sehr viel einfacher erledigen (auch wenns in dem Fall kein Einzeiler geworden wäre, aber es ist leichter verständlich). Wobei man wenn man auf die Windows Boardmittel angewiesen ist nur entweder die nicht ganz so tollen VBScript / JScript hat oder eben die Powershell (wobei die glaub ich nicht immer installiert sein muss). Ich hab zuletzt für solche Sachen Python verwendet, das ist recht einfach, aber man braucht halt den Interpreter auf dem PC.
 
Einzeiler in PowerShell:
Code:
gci "E:\schnipsel" -Recurse | ? { !$_.PsIsContainer -and $_.FullName -like "*#*" } | % { Move-Item $_ ($_.FullName -replace "#","-") }
anstatt -like (Pattern Matching, also mit * und ?) könntest du -match mit einem Regex verwenden. -replace nimmt einen Regex entgegen und ersetzt mit dem Folgestring.

Kurzum: Listet alle Dateien rekursiv, die ein # enthalten und ersetzt die Raute mit nem Bindestrich.

Keine fünf Minuten Arbeit und auch keine drei Stunden. ;)
 
Zuletzt bearbeitet: (Korrektur FullName)
Powershell steht mir leider nicht zur Verfügung...

Aber danke für den Post, gibt bestimmt jemanden, der das nutzen kann!

LG, Suma
 
@Suma:
Was für ein Betriebssystem benutzt du?
Das letzte Windows OS ohne Powershell ist Windows Vista (ok Windows Phone hats glaub ich auch nicht standardmäßig dabei :freak:)

unter Windows 7 hast du Powershell immer installiert inklusive der ISE (ein Editor mit Syntaxhervorhebung/integrierter Hilfe/debugging usw..)
 
Zurück
Oben