Dateinamen per Batch Umbennenen (alles hinter 4 stelliger Zahl entfernen)?

geri3d  08.11.2020, 08:04

Darf es auch eine VBScript Datei sein?

Wie sehen die Dateinamen aus (Beispiele)?

trashy294 
Fragesteller
 08.11.2020, 21:56

ja darf, Beispiele habe ich seperat gepostet weil ich nur 15 Zeichen hatte...

4 Antworten

Folgenden Quelltext anpassen mit dem Pfad und abspeichern als *.vbs Datei.

On Error Resume Next

dim neuName
dim gefunden
dim jahr
dim path

Set fso = CreateObject("Scripting.FileSystemObject")

path = "D:\Users\Edge\Desktop\temp\"

' Hier muss der Pfad nochmal eingetragen werden

Set Folder=fso.GetFolder("D:\Users\Edge\Desktop\temp")
For Each File in Folder.Files

    dateiNameExt=right(File.Name,len(File.Name) - InStrRev(File.Name,".")+1)

    tempName=left(File.Name,InStrRev(File.Name,".")-1)
    
    jahr = ""
    
    for i = len(tempName) to 1 step - 1
        s = mid(tempName,i,1)
        if gefunden then
            neuName = s  & neuName
        else
            if asc(s)>47 and asc(s)<58 then
                jahr = s & jahr
                if len(jahr)=4 then
                    gefunden=true
                    if mid(tempName,i-1,1)="." then
                        dotEntfernen=true
                    end if
                    
                end if
            end if
        end if
    next
    
    if not gefunden then
        neuName=tempName
    else
        gefunden=false
    end if
    
    if dotEntfernen then
        neuName=left(neuName,len(neuName)-1)
        dotEntfernen=false
    end if

    fso.MoveFile path & File.Name, path & neuName & dateiNameExt
    
    neuName=""

Next

Woher ich das weiß:eigene Erfahrung
geri3d  09.11.2020, 09:51

Edit weil ich übersehen habe, dass du statt . ein Leerzeichen willst.

dim neuName
dim gefunden
dim jahr
dim path

Set fso = CreateObject("Scripting.FileSystemObject")

path = "D:\Users\Edge\Desktop\temp\"

Set Folder=fso.GetFolder("D:\Users\Edge\Desktop\temp")
For Each File in Folder.Files

    dateiNameExt=right(File.Name,len(File.Name) - InStrRev(File.Name,".")+1)

    tempName=left(File.Name,InStrRev(File.Name,".")-1)
    
    jahr = ""
    
    for i = len(tempName) to 1 step - 1
        s = mid(tempName,i,1)
        if gefunden then
            neuName = s  & neuName
        else
            if asc(s)>47 and asc(s)<58 then
                jahr = s & jahr
                if len(jahr)=4 then
                    gefunden=true
                    if mid(tempName,i-1,1)="." then
                        dotEntfernen=true
                    end if
                    
                end if
            end if
        end if
    next
    
    if not gefunden then
        neuName=tempName
    else
        gefunden=false
    end if
    
    if dotEntfernen then
        neuName=left(neuName,len(neuName)-1)
        dotEntfernen=false
    end if

    neuName = Replace(neuName,"."," ")

    fso.MoveFile path & File.Name, path & neuName & dateiNameExt
    
    neuName=""

Next
1
Erzesel  09.11.2020, 12:48

Macht einigermaßen was es soll. ich wäre nicht der Esel, wenn ich nicht ein Aaaaber nachschieben würde.

versuche es mal mit meinem Extremdateinamen:

text.bla. 2025!.text.26.sehr & Komplex.8.text.2011.irgendwas.2019.noch.mehr.Das.ist kein.Jahr-12011.das auch nicht2116.jpg

(ich baue gerne richtig böse Testobjekte,. ich bin fast irre geworden, als mein Script über den Dateinamen " (2) TERRIFYING TALENT! Freaky Magician GIRL Scares Judges & Audience On Asia's Got Talent! - YouTube.url" gestolpert ist und Powerschell nur noch Fehler ausgespuckt hat)

Ich war anfangs auch auf dem Trichter die Zeichen von rechts nach links einzeln abzuscannen. ...aber wozu wenn man den string mit split() an den Punketen zerlegen kann. das geht auch in VBScript und VBS kann auch mit RegEx umgehen (\b[12][09][0-9][0-9]\b sucht in einem String nach genau 4 Zahlen begrenzt durch Zeichen, welche weder Buchstabe noch Zahl sind und mit einem Wert 1900 und 2099 ...6324 oder 0578 sind unmöglich relevante Jahreszahlen ... Ok der Film 2012 könnt evtl betroffen sein, da hoffen wir das da noch etwas rechts steht...)

Allerdings können solche Dateinamen die Irrsinigsten Konstellationen haben und egal wie ich splite es ist möglich, das in einem Feld 2 Jahreszahlen stehen , dann ist bei VBScript immer noch die Linke im Block der Treffer ,denn VBS kan leider nicht mit einem "negative lookahead" von "nicht von Links" (schreibe bewusst nicht "von Rechts") suchen. Ergo bedarf es extra Prüfungen um alle Idiodien zu berücksichtigen...Ich habe schon Pferde vor der Apotheke kotzen sehen...

VBScript wird dies Funktion auch nicht mehr bekommen, da diese Sprache von M$ nicht mehr weiterentwickelt wird (sterbende Sprache)

Letztlich hab ich mich nur für Batch und Powershell entschieden, Da das Dateimanagment relativ simpel ist und Powershell auch komplexe Befehle in einer Kommandozeile ausführen kann.

Wofür Du die Zeilen 17..46 brauchst . (ohne Sonderfälle zu berücksichtigen) erledige ich mit einer Zeile:

powershell "((([regex]'\.*[ ]*\b[12][09][0-9][0-9]\b(?!.*\b[12][09][0-9][0-9]\b)').split('irrsinniger 1983 0631 2020  Dateiname',2)[0]) -replace'\.',' ' -replace '[&\!'']','' -replace'\s+',' ' ).trim()"

Trotzdem freut es mich immer wenn jemand kreativ an eine Lösung herangeht und das ist die Deine auf jeden Fall. Ich käme garnicht mehr ernsthaft auf die Idee einen String "zu Fuß"(Zeichen für Zeichen) zu durchkämmen.

Mit split(string".",-1,1) und Join(StringArray," ") wären alle Punkte Spaces. dazwischen kann man das StringArray von hinten mit RegEx auf eine Jahreszahl durchsuchen.

Das klappt übrigens in allen Sprachen so.

Denke bitte nicht das ich einfach nur herummosere. Ich selbst freue mich über jeden Fehler der in meinen Pogrammen/Scripten gefunden wird, ist es doch ein Grund immer weiter zu lernen. (sonst würde ich heute nicht das können was ich kann)

1
geri3d  09.11.2020, 13:26
@Erzesel

AAAAAAAAAAAAAAAAAAAAAber die Aufgabenstellung war doch

alles hinter 4 stelliger Zahl entfernen
1
Erzesel  09.11.2020, 13:39
@Erzesel

stimmt , hast recht 😮🤮 .

Da habe ich mich wohl von dem 2019 als Trenner in den Dateinamensbeispielen leiten lassen. (und meiner VideoSammlung , welche geradezu vor solchen Namen strotzt)

Kannst Du mal sehen wozu Erfahrungsmuster verleiten können.

Sollte jegliche 4 Stellige gesucht werden: *Schnips*

set "regex=\.*[ ]*\b[0-9][0-9][0-9][0-9]\b(?!.*\b[0-9][0-9][0-9][0-9]\b)"

...das wars... 🤩

1

In Sachen Mustererkennung ist unser Gehirn unschlagbar (ein Blick und wir sehen was die Letze Jahreszahl ist und was nur eine 4-stellige Zahl oder sonstwas in der Art ist).

Zugegeben ich musste auch erst überlegen, wie ich eine Entscheidung treffe, was was ist.

Ich habe also folgende Kriterien gesetzt:

  • am Rechner relevant sind nur die Jahre 1900 bis 2099 überhaupt in Sachen Dateien .(1. Stelle 1 oder 2, 2. Stelle 0 oder 9, 4. und 4. Stelle 0 bis 9)
  • Die Zahl soll ein ganzes Wort sein also nicht innerhalb von Buchstaben oder anderen Zahlen (eine 5-Stellige Zahl ist kein Jahr)

Batch ist alles andere als freundlich, wenn es um die Verarbeitung von Strings geht. Deshalb lasse ich in einem kleinen PowershellScript den String verarbeiten.

Der Reguläre Ausdruck für die die Suche von Rechts nach Links ist sehr selten und eine Logische Umkehrung: suche solange nicht die gefundene Jahreszahl bis zum Ende, dann ist es die Gefunde 😮😬 (total total Gaga). https://www.regular-expressions.info/lookaround.html

funktionstest.cmd

@echo off
chcp 65001 >nul
  rem extra fieser DateiName mit vielem  was  nur  aussieht wie ein Jahr
set "FileName1=text.bla. 2025!.text.26.sehr & Komplex.8.text.2011.irgendwas.2019.noch.mehr.Das.ist kein.Jahr-12011.das auch nicht2116.jpg"
set "FileName2=zhfsovho.sfsvfv.tt.2625.ivfbd.fdb.aber dass 2019.das.hier.soll.alles.verschwinden.avi"
set "FileName3=text.bla. 2025.text.26.irgendwatext.test-ÄÖÜ.text.26.irgendwas.8.text.vvfkwgvk.2019.noch.mehr.text.worte.bmp"


  rem Suchpattern:  negative lookahead, teile am letzen Vorkommen eines ganzen Wortes von 1900 bis 2099 entferne vorangehenden Punkte oder Leerzeichen
set "regex=\.*[ ]*\b[12][09][0-9][0-9]\b(?!.*\b[12][09][0-9][0-9]\b)"
  rem Zeichen, welche aus dem Dateinamen entfernt werden sollen &!'
set "rgxSpclChars=[&\!'']"


  rem arbeite  Dateinamenliste ab....
for %%a in ("%FileName1%","%FileName2%","%FileName3%") do (
      rem teile den nackten Namen der Datei an der letzten Jahreszahl (regex) in 2 Teile, wähle den ersten Teil [0] und  erstze verbleibende Punkte  durch Leerzeichen, entferne einige Sonderzeichen und vereinzelne Leerzeichen
    for /f "usebackq tokens=*" %%c in (`powershell "((([regex]'%regex%').split('%%~na',2)[0]) -replace'\.',' ' -replace '%rgxSpclChars%','' -replace'\s+',' ' ).trim()"`) do (
          rem zeige  Originaldateiname
        echo %%~nxa
          rem Zeige Neuen
    echo %%c%%~xa
    echo.
   )
)
pause

Das ganze als Droptarget. Du Kannst ca. 100 Dateien auf einmal auf die Batch ziehen ( je nach Pfadlängen ...maximum insgesamt 8100 Zeichen)

@echo off
chcp 65001 >nul
if "%~1"=="" (
    echo Zum Umbenennen ziehe die gewünschten Dateien auf "%~nx0" .
    timeout 5 >nul
    exit /b
)


set "regex=\.*[ ]*\b[12][09][0-9][0-9]\b(?!.*\b[12][09][0-9][0-9]\b)"


set "rgxSpclChars=[&\!'']"


  rem arbeite  Dateinamenliste ab.... (dateien, welche  auf die Batch gezogen wurden)
for %%a in (%*) do (
      rem in Subroutine auslagern, spart Eiertanz mit Variablen (siehe Kommentar @Sub)
    call :renameIt "%%~fa"
)
pause
exit /b


:renameIt 
  rem Killer-Dateinamen fixen
  rem das Powershellscript vertägt keine SingleQotes (') in Dateinamen!
  rem maskieren durch Vedoppeln, dann passts
set "__dummy=%~n1"
set "__dummy=%__dummy:'=''%"
for /f "usebackq tokens=*" %%c in (`powershell "((([regex]'%regex%').split('%__dummy%',2)[0]) -replace'\.',' ' -replace '%rgxSpclChars%','' -replace'\s+',' ' ).trim()"`) do (
    set "newName=%%c"
)
  rem nur  umbenennen, wenn der Name  geändert wurde 
if "%~nx1" neq "%newName%%~x1" (
    echo "%~nx1"
    echo "%newName%%~x1"
    ren "%~f1" "%newName%%~x1" && (
        echo Erfolgreich umbenannt
    )||(
        echo da hat was nicht  geklappt...
    )
    echo.
) else (
    echo nichts zu tun
)
exit /b

...oder mit automatischer Dateisuche. (im Batchordner)

@echo off
chcp 65001 >nul

set "regex=\.*[ ]*\b[12][09][0-9][0-9]\b(?!.*\b[12][09][0-9][0-9]\b)"
set "rgxSpclChars=[&\!'']"

for %%a in (*) do (
    call :renameIt "%%~fa"
)
pause
exit /b


:renameIt 
set "__dummy=%~n1"
set "__dummy=%__dummy:'=''%"
for /f "usebackq tokens=*" %%c in (`powershell "((([regex]'%regex%').split('%__dummy%',2)[0]) -replace'\.',' ' -replace '%rgxSpclChars%','' -replace'\s+',' ' ).trim()"`) do (set "newName=%%c")
if "%~nx1" neq "%newName%%~x1" (
    echo "%~nx1"
    echo "%newName%%~x1"
    ren "%~f1" "%newName%%~x1" && (
        echo Erfolgreich umbenannt
    )||(
        echo da hat was nicht  geklappt...
    )
    echo.
) else (
    echo nichts zu tun
)
Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
trashy294 
Fragesteller
 10.11.2020, 00:37

Vielen Dank! Ich habe die letzte Version gewählt weil ich die super flexibel in unterschiedlichen Ordnern verwenden kann. Klappt Super, habe nur das /b hinter exit entfernt.

0
Erzesel  10.11.2020, 08:28
@trashy294

Wenn ich fragen darf.. Hatte es einen bestimmten Grund, weshalb Du auf das /b verzichtest?

Der Schalter / b sorgt lediglich dafür, das die Console nicht geschlossen wird, wenn eine Batch in einem Consolen-Fenster gestartet wird.

Am Ende einer Subrudine muss dieser sogar verwendet werden.

https://docs.microsoft.com/de-de/windows-server/administration/windows-commands/exit

PS: Wenn Du zufrieden bist, kannst Du unbesorgt die Diversen Buttons und Knöpfe drucken.

😅Sonst bezahlt uns GF nicht...

0
Erzesel  10.11.2020, 08:40
@trashy294

Ach übrigens...

Wie Du in den Kommentaren von @Geri3d ersehen konntest, hatte ich implizit verstanden, das es um eine Jahreszahl geht, wenn gleich Du dies nicht erwähnt hattest.

Lag ich mit meinem Blick in die Glaskugel richtig ?

0
marv1277  02.04.2021, 00:29

Hallo Erzesel,

deine Batch ist super, allerdings benötige ich eine leicht abgewandelte Version und bekomme dein Script leider nicht angepasst. Ich brauche eigentlich fast das gleiche Script wie der Themen Starter, nur dass bei mir die Jahreszahl stehen bleiben soll. Soweit ich verstanden habe kann ich mit deinem Script aber leider nur alles hinter oder Vor der Jahreszahl als Dateinamen setzen. Gibt es da auch eine Andere Lösung? Ich bin leider nirgendwo fündig geworden und würde mich sehr über Hilfe freuen!

Danke und lieben Gruß Marvin

0

Hallo Erzesel,

deine Batch ist super, allerdings benötige ich eine leicht abgewandelte Version und bekomme dein Script leider nicht angepasst. Ich brauche eigentlich fast das gleiche Script wie der Themen Starter, nur dass bei mir die Jahreszahl stehen bleiben soll. Soweit ich verstanden habe kann ich mit deinem Script aber leider nur alles hinter oder Vor der Jahreszahl als Dateinamen setzen. Gibt es da auch eine Andere Lösung? Ich bin leider nirgendwo fündig geworden und würde mich sehr über Hilfe freuen!

Danke und lieben Gruß Marvin

Alles was funktioniert soll mir recht sein! solange ich kein zusätzliches Programm benötige und ich es unter Windows ausführen kann.

Beispiele:

text.bla.text.26.irgendwas.8.text.vvfkwgvk.2019.noch.mehr.text.worte.jpg

zhfsovho.sfsvfv.tt.2625.ivfbd.fdb.vnzk.2019.das.hier.soll.alles.verschwinden.avi

Soll werden zu:

text bla text 26 irgendwas 8 text vvfkwgvk.jpg

zhfsovho sfsvfv tt 2625 ivfbd fdb vnzk.avi