Dateiname beim Kopieren notfalls ändern?

  • Beispiel Massenverschiebung von Dateien
    [autoit]

    For $i = 1 To $aFileList[0]
    $iAttrib = FileGetAttrib($pDeskDir & "\" & $aFileList[$i])
    If $iAttrib <> "D" Then
    $aSplitB = StringSplit($aFileList[$i],".")
    $sString = $aSplitB[$aSplitB[0]]
    Select

    [/autoit] [autoit][/autoit] [autoit]

    ; Textdateien
    Case $sString = "txt" Or $sString = "pdf" Or $sString = "doc"
    ; hier muss evtl ne If-Else-Bedingung hin
    FileMove($pDeskDir & "\" & $aFileList[$i],$pTextFiles & "\" & $aFileList[$i],9)
    $zTextFiles += 1

    [/autoit] [autoit][/autoit] [autoit]

    ; ausführbare Dateien
    Case $sString = "exe" Or $sString = "bat" Or $sString = "reg"
    ; hier muss evtl ne If-Else-Bedingung hin
    FileMove($pDeskDir & "\" & $aFileList[$i],$pRunables & "\" & $aFileList[$i],9)
    $zRunables += 1

    [/autoit] [autoit][/autoit] [autoit]

    ; gepackte Dateien
    Case $sString = "7z" Or $sString = "iso" Or $sString = "isz" Or $sString = "rar" Or $sString = "zip"
    ; hier muss evtl ne If-Else-Bedingung hin
    FileMove($pDeskDir & "\" & $aFileList[$i],$pGepacktes & "\" & $aFileList[$i],9)
    $zGepacktes += 1

    [/autoit]


    Hey, ich steh grad auf der Leitung. Ich möchte mir hier noch eine Prüfung einbauen, dass, falls eine Datei schon existiert, die zu kopierende Datei umbenannt wird.
    zB nach "Dateiname__Kopie_1" oder _2 oder _3, je nachdem wieviele Dateien halt schon mit diesem Namen vorhanden sind.
    Nur fällt mir momentan nicht ein, wie ich diese Prüfungsroutine schreiben soll.

    Könnt ihr mir da Tipps geben?

    MfG Lo..

  • so ungetestet.
    Einfach in einer Schleife prüfen, ob die Datei existiert und ggf. hochzählen.

    [autoit]

    $sDateiname_basis = $aFileList[$i] ;ohne Dateiendung
    $sDateiname = $sDateiname_basis & ".dateiendung"
    $iZaehler = 0

    [/autoit][autoit][/autoit][autoit]

    While FileExists($sDateiname)
    $iZaehler += 1
    $sDateiname = $sDateiname_basis & "__Kopie_" & $iZaehler & ".dateiendung"
    WEnd

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite($sDateiname & @CRLF)

    [/autoit]
  • Danke Tweaky

    Allerdings war es dann doch nicht soooo einfach. Hab es nun so gelöst

    [autoit]

    Func _my_Filemove($quelle, $ziel, $attrib = 0)
    Local $split1, $split2, $string, $filelist, $newfile, $anhang = "_Kopie_", $count = 1
    $split1 = StringSplit($ziel, "\") ;
    $string = StringReplace($ziel, $split1[$split1[0]], "", -1) ; Zielordner aus dem Zielpfad bekommen
    $split2 = StringSplit($split1[$split1[0]], ".") ; zu kopierende Datei in Name und Endung aufteilen
    If Not FileExists($ziel) Then
    FileMove($quelle, $ziel, 9)
    Else
    $filelist = _FileListToArray($string, $split2[1] & "*") ; Filter auf Dateinamen beschränken
    For $i = 1 To $filelist[0]
    If StringInStr($filelist[$i], $split2[1] & $anhang) = True Then $count += 1
    Next
    $newfile = $string & "\" & $split2[1] & $anhang & $count & "." & $split2[2]
    FileMove($quelle, $newfile, $attrib)
    EndIf
    EndFunc

    [/autoit]


    Jetzt brauch ich nur noch überall im Script die vielen "FileMoves" gegen diesen Funktionsnamen austauschen.
    Aber vielleicht kann man das noch besser schreiben?

  • Bei deiner Lösung funktioniert es allerdings nicht wenn z.B. "test_Kopie_1" und "test_Kopie_3" vorhanden, aber "test_Kopie_2" fehlt.
    Dann heißt die neue Datei "test_Kopie_3", obwohl diese bereits vorhanden ist.
    Teste es einfach mal.

    So würde ichs machen.

    [autoit]

    Func _my_Filemove($quelle, $ziel, $attrib = 0)
    Local $split1, $split2, $string, $filelist, $newfile, $anhang = "_Kopie_", $count = 0
    Local $sDrive = "", $sDir = "", $sFilename = "", $sExtension = ""

    [/autoit][autoit][/autoit][autoit]

    Local $aPathSplit = _PathSplit($ziel, $sDrive, $sDir, $sFilename, $sExtension)

    [/autoit][autoit][/autoit][autoit]

    If Not FileExists($ziel) Then
    FileMove($quelle, $ziel, 9)
    Else
    While FileExists($ziel)
    $count += 1
    $ziel = $sDrive & $sFilename & $anhang & $count & $sExtension
    WEnd
    FileMove($quelle, $ziel, $attrib)
    EndIf
    EndFunc ;==>_my_Filemove

    [/autoit][autoit][/autoit][autoit][/autoit]
  • Habs eben probiert mit deiner Funktion und etwas kurioses festgestellt:

    1. Kopiervorgang war erfolgreich ==> file A wurde erfolgreich verschoben von Ordner 1 nach Ordner 2
    2. File A in Ordner 1 kopiert und erneut die Funktion ausgeführt
    3. Kopiervorgang NICHT erfolgreich und File A wurde zu File A_Kopie_1 in Ordner 1

    wtf...
    dabei zeigt mir _ArrayDisplay($aPathSplit) die korrekten Werte an?!?!

    • Offizieller Beitrag

    Ich hatte mal eine kleine Funktion geschrieben, mit der man einen Dateinamen zurückbekommt, der noch nicht existiert (Zähler angehängt).
    Diese Funktion kannst Du vor dem FileMove mit dem Zielnamen aufrufen und mit dem zurückgegebenen Dateinamen dann FileMove aufrufen.

    Spoiler anzeigen
    [autoit]


    $sFilename = @AutoItExe
    $sFilename = _GetUniqueFileName($sFilename)
    If @error Then
    ConsoleWrite('Fehler = ' & @error & @CR)
    Else
    ConsoleWrite('Dateiname = "' & $sFilename & '"' & @CR)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; 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 (http://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

    [/autoit]
  • Sooooo, erstmal @Oscar
    Danke für dein Script, doch diesmal brauch ich es nicht. Mit dem Umstieg von _FileListToArray() zur While-Schleife besteht das Problem was @Tweaky beschrieb nun nicht mehr.

    @Tweaky
    Ich habe, wie bereits erwähnt, von deinem Beispiel die While-Schleife übernommen. Somit tritt das von dir beschriebene Problem nun nicht mehr auf. Danke dafür.
    Offensichtlich stimmt irgendwas nicht mit der Funktion _PathSplit(). Ich habs mehrfach getestet, auch mit mehrfach verschachtelten Ordnern, weil ich zwischendurch dachte,
    _PathSplit() gibt trotz korrekter Anzeige per _ArrayDisplay() einen Ordner zu wenig zurück. Doch das scheint auch nicht der Fall zu sein. Wenn die Zieldatei, selbst in den verschachtelten
    Ordnern, bereits existiert, dann landet die zu erstellende Kopie immer auf dem Desktop.

    Ich hab mal mein Testscript zum Vergleich angepasst um zu verdeutlichen, was genau ich meine.

    Hier das Beispiel
    [autoit]

    #include "array.au3"
    #include "file.au3"

    [/autoit] [autoit][/autoit] [autoit]

    $testquelle = "\AAxtestdir\"
    $testziel = "\BBxtestdir2\"

    [/autoit] [autoit][/autoit] [autoit]

    $quelle = @DesktopDir & $testquelle & "1test.txt"
    $ziel = @DesktopDir & $testziel & "1test.txt"

    [/autoit] [autoit][/autoit] [autoit]

    $quelle2 = @DesktopDir & $testquelle & "2test.txt"
    $ziel2 = @DesktopDir & $testziel & "2test.txt"

    [/autoit] [autoit][/autoit] [autoit]

    _my_Filemove($quelle, $ziel, 9)
    _your_Filemove($quelle2, $ziel2, 9)

    [/autoit] [autoit][/autoit] [autoit]

    Func _my_Filemove($quelle, $ziel, $attrib = 0)
    Local $split1, $split2, $string, $filelist, $newfile, $anhang = "_Kopie_", $count = 1
    $split1 = StringSplit($ziel, "\")
    $split2 = StringSplit($split1[$split1[0]], ".")
    $string = StringReplace($ziel, $split1[$split1[0]], "", -1)
    If Not FileExists($ziel) Then
    FileMove($quelle, $ziel, 9)
    Else
    $newfile = $string & "\" & $split2[1] & $anhang & $count & "." & $split2[2]
    While FileExists($newfile)
    $count += 1
    $newfile = $string & "\" & $split2[1] & $anhang & $count & "." & $split2[2]
    WEnd
    FileMove($quelle, $newfile, $attrib)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _your_Filemove($quelle, $ziel, $attrib = 0)
    Local $split1, $split2, $string, $filelist, $newfile, $anhang = "_Kopie_", $count = 0
    Local $sDrive = "", $sDir = "", $sFilename = "", $sExtension = ""

    [/autoit] [autoit][/autoit] [autoit]

    Local $aPathSplit = _PathSplit($ziel, $sDrive, $sDir, $sFilename, $sExtension)
    If Not FileExists($ziel) Then
    FileMove($quelle, $ziel, 9)
    Else
    While FileExists($ziel)
    $count += 1
    $ziel = $sDrive & $sFilename & $anhang & $count & $sExtension
    WEnd
    FileMove($quelle, $ziel, $attrib)
    EndIf
    EndFunc ;==>_your_Filemove

    [/autoit]


    Geht das vielleicht noch jemanden so????

  • musst du nicht einfach nur

    while fileexist($filename)
    $filename & = " (1)"
    wend

    damit sollte er wie das bei windoof üblich ist ein " (1)" an die datei anhägen bis es den file nicht gibt oder hab ich noch einen denkfehler drin?

  • mit der dateiendung das ist mir bewusst.^^ sollte schon eher wie im beispiel $dateiname & $anhang & $endung sein

    Ist das Problem mitlerweile durch oder soll nochmal jemand drübersehen?