batch2go
Goto Top

CMD - Stern und Sonderzeichen in Dateinamen entfernen

Gueten Tag zusammen

Mit grossem Interesse lese ich euer Beiträge (und würde mich an dieser Stelle als Azubi bezeichnen).
Eure Tips und Tricks haben mir schon bei manchem Problem geholfen.
Nun aber komme ich nicht mehr weiter...Folgendes:

In einem batch wird der Dateiname an ein Programm weitergereicht.
Nun kann es vorkommen, dass der Dateiname das Zeichen * (Stern) beinhaltet.
Bsp: "Adobe Acrobat XI * Adobe PDF-Konvertierungseinstellungen.pdf"

Bis jetzt habe ich es nicht geschfft, das Zeichen * zu entfernen oder durch das _ zu ersetzen.

Folgende Varianten habe ich schon ausprobiert...

Variante 1
setlocal enabledelayedexpansion
SET "Filename=%Filename:\=_%"
SET "Filename=%Filename:/=_%"
SET "Filename=%Filename::=_%"
SET "Filename=%Filename:?=_%"
SET "Filename=%Filename:<=_%"
SET "Filename=%Filename:>=_%"
SET "Filename=%Filename:|=_%"
SET "Filename=%Filename:"=_%"
SET "Filename=%Filename:*=_%"

Variante 2
setlocal enabledelayedexpansion
SET "search=: / . ? & = % * "

for %%s in (!search!) do (
SET "Filename=!Filename:%%~s=_!"
)


Hat jemand von euch eine Idee?
Über eure Hilfe würde ich mich freuen, batch2go

Content-Key: 233399

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

Printed on: April 24, 2024 at 17:04 o'clock

Member: Endoro
Endoro Mar 22, 2014 at 13:27:07 (UTC)
Goto Top
Hey,
Wie hast du die Sterne da reinbekommen? Das ist weit jenseits des Erlaubten.
Mit diesen Ersetzen-Funktionen geht es natürlich jedenfalls nicht. Nimm einen Goto-Loop oder eine For-Schleife.
Gruss, Endoro.
Member: Pjordorf
Pjordorf Mar 22, 2014 at 13:33:46 (UTC)
Goto Top
Hallo,

Zitat von @batch2go:
Nun kann es vorkommen, dass der Dateiname das Zeichen * (Stern) beinhaltet.
Dir ist schon klar das dieses * Zeichen eben nicht in einen Dateinamen verwendet werden kann? Wo also kommen diese Dateien mit diesen angeblichen Stern * darin dann her? Welches Dateisystem liegt darunter, NTFS sicherlich nicht, oder? Mit welchem Zeichensatz wird es dargestellt oder wurde es erzeugt (nicht das es sich um einzulässiges Zeichen eines anderen Zeichensatzes handelt)? Und, mit welchem OS arbeitest du hier?

Bsp: "Adobe Acrobat XI * Adobe PDF-Konvertierungseinstellungen.pdf"
Versuch mal eine datei mit namen "Das ist eine * Stern Datei.txt" zu erzeugen.

Mal mit einen Hexeditor dir die Verzechnissinhaltsliste angeschaut?

Gruß,
Peter
Member: rubberman
rubberman Mar 22, 2014 at 13:39:57 (UTC)
Goto Top
Hallo batch2go, willkommen im Forum.

Muss es in diesem Fall unbedingt Batch sein? Nicht dass es nicht auf umständliche Art und Weise möglich wäre das mit Batch umzusetzen, die Performance würde aber extrem darunter leiden ...

Grüße
rubberman
Member: batch2go
batch2go Mar 22, 2014 at 14:27:40 (UTC)
Goto Top
Hallo Endoro

Vielen Dank fürs Feedback

Mittels batch soll/muss ein zu druckendes Dokument direkt weiterverarbeitet werden.
Konkretes Beispiel:
Der unter
http://help.adobe.com/de_DE/acrobat/using/WS58a04a822e3e50102bd61510979 ...
dargestellte Inhalt wird über einen PS-Drucker direkt an einen Port von RedMon weitergegeben.
RedMon startet dann folgendes batch:

...
SET "Filename=%REDMON_DOCNAME%"
SET "Filename=%Filename:\=_%"
SET "Filename=%Filename:/=_%"
SET "Filename=%Filename::=_%"
SET "Filename=%Filename:?=_%"
SET "Filename=%Filename:<=_%"
SET "Filename=%Filename:>=_%"
SET "Filename=%Filename:|=_%"
SET "Filename=%Filename:"=_%"

ren %1 "%Filename%"
...

Zu Deienm Vorschlag...Nimm eine ...Goto-Loop oder eine For-Schleife...
Hättest Du mir einen kokreten Codeschnipselvorschlag, das wäre toll!

PS:Das Ganze läuft unter Windows 8.1

batch2go
Member: batch2go
batch2go Mar 22, 2014 at 14:35:06 (UTC)
Goto Top
Hallo Peter

Auch Dir - zuerst - vielen Dank fürs Feedback.
Vielleicht bringt meine Antwort für Endoro etwas Licht ins Dunkel.
Die Generierung des Dateinamens erfolgt vollumfälling über das Windows Spoolsystem.
Dieses kann leider Dateinamen generieren - das macht einem schon Angst... face-smile

PS: Das Zeichen * ist als 2A (Hex) gespeichert

Gruess batch2go
Member: rubberman
rubberman Mar 22, 2014 at 14:37:13 (UTC)
Goto Top
Hallo batch2go,

zeichenweise könnte bspw. so aussehen:
@echo off &setlocal

set "filename=;a/b\c:d?e*f<g>h|i"j !%%^^^&=~.ext"  

:: Vorher ::
setlocal EnableDelayedExpansion
echo !filename!
endlocal


set "newname=" &set "as=*" &set "qm=?" &set "qt=""  
for /f delims^=^ eol^= %%i in ('cmd /von /u /c "echo(!filename!"^|find /v ""^|findstr .') do (  
  set "char=%%i"  
  setlocal EnableDelayedExpansion
  for %%j in ("\" "/" ":" "^!as^!" "^!qm^!" "^!qt^!" "<" ">" "|") do if "!char!"=="%%~j" set "char=_"  
  for /f delims^=^ eol^= %%j in ("!newname!!char!") do (endlocal &set "newname=%%j")  
)
set "filename=%newname%"  


:: Danach
setlocal EnableDelayedExpansion
echo !filename!
endlocal

pause
Wie gesagt, die Performance ist da nicht berauschend...

Grüße
rubberman
Member: batch2go
batch2go Mar 22, 2014 at 14:43:25 (UTC)
Goto Top
Hallo Rubberman

Auch Dir vielen Dank für das Feedback
Danke fürs Willkommen im Forum - vielleicht muss ich noch etwas das Gespür kriegen, wie man wo und in welcher Form antwortet.
Ich tu aber mein Bestes...

Zu Deiner Frage/Vorschlag...
Die Lösung müsste sich nicht zwingend innerhalb eines Batches finden, vorausgesetzt das batch ruft ein XY auf und stellt den 'korrigierten' Dateinamen dem batch wieder zur Verfügung.
Im ersten Schritt wäre ich über jeden funktionierenden Vorschlag froh.


Gruess batch2go
Member: batch2go
batch2go Mar 22, 2014 at 14:55:30 (UTC)
Goto Top
Hallo rubberman

Vielen Dank - Du warst mit dem Codschnipsel schneller als ich mit meiner Textantwort - Hut ab!
Gerne werde ich mir Deinen Vorschlag genauer anschauen.
Ich melde mich dann wieder...


Gruess batch2go
Member: rubberman
rubberman Mar 22, 2014 updated at 15:08:02 (UTC)
Goto Top
Hallo batch2go.

vorausgesetzt das batch ruft ein XY auf und stellt den 'korrigierten' Dateinamen dem batch wieder zur Verfügung

Dann kannst du auch meinen Vorschlag von oben nutzen. Zwischen unterschiedlichen Scripten zu wechseln (bspw. für jeden Dateiname ein VBScript / JScript / Powershellscript o.Ä. aufzurufen) "verschlimmbessert" die Performance höchstens. Wenn, dann komplett in einer anderen Sprache ...

Grüße
rubberman
Member: colinardo
colinardo Mar 22, 2014 updated at 15:49:10 (UTC)
Goto Top
Hi batch2go,
kannst du z.B. auch mit einem VB-Script machen:
Set regex = CreateObject("vbscript.regexp")  
strFile = WScript.Arguments(0)
regex.Global = True
regex.Pattern = "[\\/:?<>|""*]"  
strNewFile = regex.Replace(strFile,"_")  
WScript.Echo strNewFile
das du dann so in deiner Batch aufrufst:
@echo off & setlocal
set "old_filename=bl<abl?u*b |.ext"  
for /f "delims=" %%a in ('cscript //Nologo replacechars.vbs "%old_filename%"') DO set new_filename=%%a  
echo %new_filename%
und wenn man möchte lässt sich das dann auch komplett in dein Batchscript einarbeiten ...
mit Powershell gehts so:
param([string]$strFilename)
$stringNEW = $strFilename -replace '[\\/:?<>|"*]','_'  
$stringNEW

Und mit sed für Windows geht's noch kürzer wenn das gewünscht ist.

Grüße Uwe
Member: batch2go
batch2go Mar 22, 2014 at 17:18:22 (UTC)
Goto Top
Hallo rubberman

Ich habe Deine Idee nun umgesetzt - funktioniert perfekt!
Mein Codeschnipsel siht nun wie folgt aus:

setlocal enabledelayedexpansion

set "newname=" &set "as=*" &set "qm=?" &set "qt=""
for /f delims^=^ eol^= %%i in ('cmd /v:on /u /c "echo(!filename!"^|find /v ""^|findstr .') do (
set "char=%%i"
for %%j in ("\" "/" ":" "^!as^!" "^!qm^!" "^!qt^!" "<" ">" "|") do (
if "!char!"=="%%~j" (
set "char=_"
)
)
for /f delims^=^ eol^= %%j in ("!newname!!char!") do (
set "newname=%%j"
)
)
set "filename=%newname%"

Eine Frage hätte ich noch...
Den wie von Dir verwendetene Schalter "/von" habe ich in dieser Form - beim versuchen zu verstehen wie das genau funktioniert - nicht gefunden.
Gefunden habe ich allerdings: "v:on"... und auch so übernommen.
Habe ich das korrekt interpretiert?


Gruess batch2go
Member: rubberman
rubberman Mar 22, 2014 updated at 18:20:50 (UTC)
Goto Top
Hallo batch2go,

der Doppelpunkt ist optional (zumindest auf den mir bekannten Windowsversionen). Die Art und Weise aus der Unicodeausgabe eines Strings die einzelnen Buchstaben zu verarbeiten, stammt übrigens von @pieh-ejdsch, siehe Batch Stringlänge bestimmen (zB. Zeilenlänge, Offset von Zeichen, Spaltenanzahl).

Mit deinem setlocal enabledelayedexpansion am Anfang solltest du vorsichtig sein. Ausrufezeichen in deinen Dateinamen werden so im Nu eliminiert. Das ist der Grund warum ich zur verzögerten Variablenerweiterung wechsle, wenn sie benötigt wird und mit endlocal wieder zurück zum "Normal" gehe wenn's kritisch wird. Besser du bleibst bei der Version, wie ich sie dir vorgeturnt habe face-wink

Nutze im Forum doch bitte Code Tags, dann grenzt du dein Programm vom restlichen Text ab und Einrückungen bleiben erhalten.
<code>Dein Code hier...</code>

Grüße
rubberman
Member: Loki1979
Loki1979 Jul 06, 2014 updated at 10:52:46 (UTC)
Goto Top
So Z.b. :
Wenn dann mehrere verbotene Zeichen hintereinander kommen
werden dann auch nicht zich Ersatz eingefügt !

Option Strict On
Public Class Form1

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MsgBox(CleanFilename("Ich ---- habe * immer # Hunger", "- *#", " "))
End Sub

Public Function CleanFilename(ByVal Dateiname As String, ByVal Verbotene_Zeivhen As String, ByVal Ersatzzeichen As String) As String
Dim s As String = System.Text.RegularExpressions.Regex.Replace(Dateiname, "[" & Verbotene_Zeivhen & "]+", Ersatzzeichen)
Return s
End Function

End Class

EINGANG = (( Ich ---- habe * immer # Hunger ))
VERBOTENE ZEICHEN = (( - *# ))
ERSATZZEICHEN = (( " " ))
AUSGANG = (( Ich habe immer Hunger ))

Und dann das ganze in ne schleife stecken um ganze Ordner mit Dateien zu putzen !

Z.b:

Option Strict On
Public Class Form1

Dim Verbotene_Zeichen As String = "* #?"
Dim Ersatzzeichen As String = " "

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

If FolderBrowserDialog1.ShowDialog() = DialogResult.OK Then

For Each Dateien In My.Computer.FileSystem.GetFiles(FolderBrowserDialog1.SelectedPath)
Dim Dateiname As String = IO.Path.GetFileName(Dateien)
Try
My.Computer.FileSystem.RenameFile(Dateien, Clean_Dateiname(Dateiname, Verbotene_Zeichen, Ersatzzeichen))
Catch ex As Exception
End Try
Next

End If

End Sub

Public Function Clean_Dateiname(ByVal Dateiname As String, ByVal Verbotene_Zeichen As String, ByVal Ersatzzeichen As String) As String
Return System.Text.RegularExpressions.Regex.Replace(Dateiname, "[" & Verbotene_Zeichen & "]+", Ersatzzeichen)
End Function

End Class


Test Tool Download:
https://www.dropbox.com/sh/jmml4shrlvl2jhv/AACXtqaeYx9i4hEKo3IBkfH9a/OD% ...

LG Loki1979
Member: colinardo
colinardo Jul 06, 2014 updated at 10:54:33 (UTC)
Goto Top
Hallo Loki1979,
Bitte nutze Code-Tags für das Posten von Quellcode: <code> Quellcode </code>, ansonsten kommen hier eventuell wichtige Sonderzeichen abhanden. Merci.

Grüße Uwe