#include-once
#include <File.au3>

; Beispiel:
_FileCopyMoveRek(@ScriptDir & '\*.txt', @ScriptDir & '\Textdateien\', 8)

;===============================================================================
; Function Name:   _FileCopyMoveRek($sSource, $sDest[, $iFlag])
; Description::    Verschiebt Dateien (Wildcards können benutzt werden) aus dem
;                  angegebenen Verzeichnis sowie aus dessen Unterverzeichnisse
;                  ins Zielverzeichnis.
; Parameter(s):    $sSource = Verzeichnis und Dateiname(n)
;                  $sDest = Zielverzeichnis
;                  $sFlag = 0 (default) existierende Dateien werden umbenannt
;                           1 überschreibt existierende Dateien
;                           4 verschiebt die Dateien statt sie zu kopieren
;                           8 Erstellt die Verzeichnisstruktur, falls nicht vorhanden
; Requirement(s):  #include <File.au3>
; Return Value(s): bei Erfolg = 1
;                  bei Fehler wird @error = 1 (Pfad falsch angegeben)
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _FileCopyMoveRek($sSource, $sDest, $iFlag = 0)
	Local $aSource, $aFiles, $aFolder
	$aSource = StringRegExp($sSource, '(.+\\)(.+)', 3)
	If @error Then Return SetError(1, 0, 0)
	If StringRight($sDest, 1) <> '\' Then $sDest &= '\'
	$aFiles = _FileListToArray($aSource[0], $aSource[1], 1)
	If Not @error Then
		For $i = 1 To $aFiles[0]
			If BitAND($iFlag, 1) Then
				If BitAND($iFlag, 4) Then
					FileMove($aSource[0] & $aFiles[$i], $sDest & $aFiles[$i], BitAND($iFlag, 9))
				Else
					FileCopy($aSource[0] & $aFiles[$i], $sDest & $aFiles[$i], $iFlag)
				EndIf
				If @error Then Return SetError(@error, 0, 0)
			Else
				If BitAND($iFlag, 4) Then
					FileMove($aSource[0] & $aFiles[$i], _GetUniqueFileName($sDest & $aFiles[$i]), BitAND($iFlag, 9))
				Else
					FileCopy($aSource[0] & $aFiles[$i], _GetUniqueFileName($sDest & $aFiles[$i]), $iFlag)
				EndIf
				If @error Then Return SetError(@error, 0, 0)
			EndIf
		Next
	EndIf
	$aFolder = _FileListToArray($aSource[0], '*', 2)
	If Not @error Then
		For $i = 1 To $aFolder[0]
			_FileCopyMoveRek($aSource[0] & $aFolder[$i] & '\' & $aSource[1], $sDest, $iFlag)
			If @error Then Return SetError(@error, 0, 0)
		Next
	EndIf
	Return SetError(0, 0, 1)
EndFunc   ;==>_FileCopyMoveRek

;===============================================================================
; Function Name:   _GetUniqueFileName($sPath)
; Description::    Wenn der Dateiname bereits existiert wird ein Zähler
;                  in Form von: "_(1)" an den Dateinamen angehängt.
; Parameter(s):    $sPath = kompletter Pfad der Datei
; Requirement(s):  -
; Return Value(s): bei Erfolg = der (neue) Dateiname
;                  bei Fehler wird @error = 1 (Pfad falsch angegeben)
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _GetUniqueFileName($sPath)
	Local $aPath, $sNumber = '', $iCount = 0
	$aPath = StringRegExp($sPath, '(.+\\)(.+?)(?:_\(\d*\))*(\..+)', 3)
	If @error Then Return SetError(1, 0, 0)
	While FileExists($aPath[0] & $aPath[1] & $sNumber & $aPath[2])
		$iCount += 1
		$sNumber = '_(' & $iCount & ')'
	WEnd
	Return $aPath[0] & $aPath[1] & $sNumber & $aPath[2]
EndFunc   ;==>_GetUniqueFileName