Ich weiß nun einmal mehr, warum ich kein AutoHotkey verwende: is das unübersichtliche Syntax...

. Die Loop ist komfortabel, keine Frage, weil man keine Funktion für die rekursive Suche schreiben muss, aber irgendwie erinnert mich das an AutoIt2 (wovon es ja abstammt) und den Krampf damit damals...
Da ich große Verzeichnisstrukturen habe, deren Verarbeitung in einem solchen Fall entsprechend lange dauert, braucht es natürlich eine Ausgabe über den Fortschritt. Und da ich AutoHotkey und VBS aus genannten Gründen nicht verwende, habe ich ein etwas umfangreicheres aber dafür komfortableres AutoIt-Skript zusammengebaut. Außerdem wollte ich sowieso eine Funktion zum rekursiven Finden von Dateien bauen, weil ich die vor kurzem schonmal benötigte und dann stattdessen die einfache Methode mit "dir /b /s" wählte

.
Die Ausgabe des Skriptes kann dann z.B.
so aussehen. Die erst in den letzten Minuten eingebaute Prozentanzeige ist auf dem Bild nicht zu sehen, weil es an der Stelle nicht genügend Daten zu verarbeiten hatte

.
OK, kommen wir zum Quellcode:
RecursiveExtensionRename.au3:
Code: Select all
;
; AutoIt Version: 3.3.4.0+
; Language: English
; Platform: Win2000/XP/2003/Vista/7
; Author: Dalai
;
; Last Update: 03.08.2011
;
; Script Function:
; Do recursive file search and rename extensions of files with upper-case
; extension to lower-case
;
; ----------------------------------------------------------------------------
; Set up our defaults
; ----------------------------------------------------------------------------
#include <Timers.au3>
#include "library_3340.inc"
;AutoIt einstellen:
;Shows the current script line in the tray icon tip to help debugging
AutoItSetOption("TrayIconDebug", 1)
AutoItSetOption("MustDeclareVars", 1)
; ----------------------------------------------------------------------------
; Script Start
; ----------------------------------------------------------------------------
global const $OUTINTERVAL = 500
global $arFiles
global $i, $count, $percent = 0, $time
global $sDrive, $sDir, $sName, $sExt, $_ext, $new
;-- input vars
global $Path, $Ext
if $CmdLine[0] < 2 then
MsgBox(64, "Usage", "Command: " & @ScriptName & @CRLF & _
'Parameter: "%P" jpg' & @CRLF & _
"First parameter: path to process including all subdirs (recursive)" & @CRLF & _
"Second parameter: extension to rename (use * for all files)")
Exit
EndIf
;--- Get input values
$Path = $CmdLine[1]
if (StringRight($Path, 1) == "\") then $Path = StringTrimRight($Path, 1)
$Ext = $CmdLine[2]
;--- Do some output
_ConsoleWriteLine(StringFormat("Searching for *.%s in", $Ext))
;--- Build array of files matching the pattern
$arFiles = _RecursiveFileListToArray($Path, "*." & $Ext, 1)
if IsArray($arFiles) then
_ConsoleWriteLine(StringFormat(@CRLF & "Found %d files matching *.%s", _Pred($arFiles[0]), $Ext))
_ConsoleWriteLine("Looking for files with upper-case extension ...")
;--- Init timer
$time = _Timer_Init()
;--- Loop through the generated array
for $i=1 to _Pred($arFiles[0])
;--- If time since last output was longer ago
; than specified interval
if (_Timer_Diff($time) >= $OUTINTERVAL) then
;--- calculate percentage
$percent = ($i * 100 / _Pred($arFiles[0]))
_ConsoleWriteLine(StringFormat("%d %", $percent))
;--- save new timer value
$time = _Timer_Init()
EndIf
;_ConsoleWriteLine($arFiles[$i])
;--- Split the full path into its contents
_PathSplit($arFiles[$i], $sDrive, $sDir, $sName, $sExt)
;--- Remove the leading period from the extension
$sExt = StringTrimLeft($sExt, 1)
;--- Handle the case meaning all files properly
if ($Ext == "*") then
$_ext = StringLower($sExt)
Else
$_ext = $Ext
EndIf
if (StringUpper($_ext) == $sExt) then
ConsoleWrite(StringFormat(" Rename %s ...", StringFormat("%s.%s", $sName, $sExt)))
;--- Generate new path with lower-case extension
$new = _PathMake($sDrive, $sDir, $sName, StringLower($sExt))
;--- Because FileMove() isn't able to rename a file to the same name with different case
; it must be renamed to a different name und then "moved" back to the target name
if (FileMove($arFiles[$i], $new & "$") AND (FileMove($new & "$", $new))) then
$count += 1
_ConsoleWriteLine(" OK")
Else
_ConsoleWriteLine(" Error!")
EndIf
EndIf
Next
;--- Output summary
_ConsoleWriteLine(StringFormat(@CRLF & "Finished. Renamed %d files", $count))
Else
_ConsoleWriteLine("Path not found or something went wrong!")
EndIf
library_3340.inc:
Code: Select all
#include <Array.au3>
#include <File.au3>
; #FUNCTION# ====================================================================================================================
; Name...........: _RecursiveFileListToArray
; Description ...: Finds files with specified pattern recursively
; Syntax.........: _RecursiveFileListToArray($sPath[, $sMask = "*"[, $iStdOut = 0]])
; Parameters ....: $sPath - Path to generate filelist for.
; $sMask - Optional the filter to use, default is *. Search the Autoit3 helpfile for the word "WildCards" For details.
; $iStdOut - Optional:
; |$iStdOut=0(Default) don't output anything
; |$iStdOut=1 output processed dirs only
; |$iStdOut=2 output found files only
; |$iStdOut=3 output processed dirs and found files
; Return values .: Success: an Array holding the file names
; Failure: 0 (files not found)
; @Error: 1 - $sPath invalid or not found or not accessible
; Author ........: Dalai
; Modified.......:
; Remarks .......: The array returned is one-dimensional and is made up as follows:
; $array[0] = Number of Files returned
; $array[1] = 1st File
; $array[2] = 2nd File
; $array[3] = 3rd File
; $array[n] = nth File
; Related .......: _FileListToArray
; Link ..........:
; Example .......: Not yet
; Note ..........:
;------------------------------------------------------------------------------
Func _RecursiveFileListToArray($sPath, $sMask = "*", $iStdOut = 0, $iDepth = 0)
local $tempArray, $dirArray, $resArray
local $full
;--- Exit if $sPath doesn't exist
if not FileExists($sPath) then Return SetError(1, 0, 0)
if (StringRight($sPath, 1) == "\") then $sPath = StringTrimRight($sPath, 1)
$iDepth += 1
;--- Write to console
if (Mod($iStdOut, 2) > 0) then
_ConsoleWriteLine($sPath)
EndIf
$tempArray = _FileListToArray($sPath, $sMask, 1)
if IsArray($tempArray) then
for $i=1 to $tempArray[0]
$tempArray[$i] = $sPath & "\" & $tempArray[$i]
if $iStdOut >= 2 then _ConsoleWriteLine($tempArray[$i])
Next
; _ArrayDisplay($tempArray, "temp")
if IsArray($resArray) then
_ArrayConcatenate($resArray, $tempArray, 1)
Else
$resArray = $tempArray
EndIf
EndIf
$dirArray = _FileListToArray($sPath, "*", 2)
if IsArray($dirArray) then
; _ArrayDisplay($dirArray, "dir")
for $i=1 to $dirArray[0]
$full = $sPath & "\" & $dirArray[$i]
$tempArray = _RecursiveFileListToArray($full, $sMask, $iStdOut, $iDepth)
if IsArray($tempArray) then
if IsArray($resArray) then
_ArrayConcatenate($resArray, $tempArray, 1)
Else
$resArray = $tempArray
EndIf
EndIf
Next
EndIf
if IsArray($resArray) then
$resArray[0] = UBound($resArray)
Return $resArray
EndIf
Return 0
EndFunc ;==>_RecursiveFileListToArray
;-----------------------------------------------------------
Func _ConsoleWriteLine(const $msg)
ConsoleWrite($msg & @CRLF)
EndFunc
Um die Ausgabe zu sehen, muss das Skript natürlich mit Aut2Exe als Konsolenanwendung kompiliert werden. Das nur als Hinweis an diejenigen, die das Skript verwenden möchten.
Das kompilierte Skript dann auf einen Button gelegt und los geht's:
Code: Select all
TOTALCMD#BAR#DATA
cmd /k
""E:\Eigene Dateien\Skripte\RecursiveExtensionRename.exe" "%P" jpg"
wcmicons.dll,22
Rekursives Kleinschreiben der Extension aller Bilder
-1
MfG Dalai