Verzeichnis bereinigen, letzte Version/Datei behalten

  • Hallo miteinander,
    ich habe eine Frage, ob sich folgendes mit AutoIt umsetzen lässt.
    Und zwar habe ich ein Verzeichnis in dem CAD-Daten abgespeichert werden. Das Besondere ist, das CAD-Programm erstellt bei jedem Speichern eine neu Version/Datei.
    So sieht das Verzeichnis zum Beispiel aus:
    7777_0000.asm.1
    7777_0000.asm.2
    7777_0000.asm.3
    7777_0016.prt.29
    7777_0016.prt.30
    7777_0016.prt.31
    7777_0016.drw.55
    7777_0016.drw.56
    7777_0016.drw.57
    7777_0017.drw.11
    7777_0018.drw.12

    Die Zeichen “7777_wxyz” zeigen hier den eigentlichen Dateinamen vom CAD-Programm.
    Anschließend folgt der Typ. „asm“ steht für Baugruppe, „prt“ steht für Einzelteil und drw steht für Zeichnung. Zuletzt wird an die Datei eine fortlaufende Nummer angehängt, die die Version angibt. Der Punkt trennt die Elemente Dateiname, Typ und Version voneinander.

    Im Durchschnitt befinden sich 700 Dateien im Verzeichnis.

    Dieses Verzeichnis muss somit immer wieder bereinigt und von überflüssigen Versionen/Dateien gelöscht werden und dafür versuche ich ein Script zu schreiben.

    Was ist eure Meinung dazu? Funktioniert es mit AutoIt oder soll ich mich doch mit C++/C# beschäftigen? Ein paar grobe Anhaltspunkte wären sehr hilfreich.

    Ich probiere momentan mit _FileListToArray, _ArrayUnique und _ArraySearch herum.

    3 Mal editiert, zuletzt von Joec33m (26. November 2011 um 16:11)

  • Übrig bleiben soll die höchste Version von jedem Dateinamen und dazugehörigen Typ.
    Wenn ich das Beispiel von vorhin nehme, dann sollte es so aussehen:

    7777_0000.asm.3
    7777_0016.prt.31
    7777_0016.drw.57
    7777_0017.drw.11
    7777_0018.drw.12

    • Offizieller Beitrag

    Dann sollte das hier passen:

    Spoiler anzeigen
    [autoit]

    ; == das hier simuliert ein mit _FileReadToArray eingelesenes Verzeichnis
    Local $aRead[12] = [11, _
    '7777_0000.asm.1', _
    '7777_0000.asm.2', _
    '7777_0000.asm.3', _
    '7777_0016.prt.29', _
    '7777_0016.prt.30', _
    '7777_0016.prt.31', _
    '7777_0016.drw.55', _
    '7777_0016.drw.56', _
    '7777_0016.drw.57', _
    '7777_0017.drw.11', _
    '7777_0018.drw.12']

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

    $aRet = _GetHighestVer($aRead)
    For $i = 0 To UBound($aRet) -1
    ConsoleWrite($aRet[$i] & @CRLF)
    Next

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

    Func _GetHighestVer(ByRef $a)
    Local $aType[3] = ['asm','prt','drw'], $ver
    Local $oFileVer = ObjCreate('Scripting.Dictionary')
    For $i = 1 To $a[0]
    For $j = 0 To 2
    If StringInStr($a[$i], $aType[$j]) Then
    $name = StringLeft($a[$i], StringInStr($a[$i], '.', 1, -1))
    $ver = StringTrimLeft($a[$i], StringInStr($a[$i], '.', 1, -1))
    If $oFileVer.Exists($name) Then
    If $ver > $oFileVer.Item($name) Then $oFileVer.Item($name) = $ver
    Else
    $oFileVer.Add($name, $ver)
    EndIf
    ExitLoop
    EndIf
    Next
    Next
    If $oFileVer.Count > 0 Then
    Local $aOut[$oFileVer.Count]
    Local $strKey, $colKeys = $oFileVer.Keys, $i = 0
    For $strKey In $colKeys
    $aOut[$i] = $strKey & $oFileVer.Item($strKey)
    $i += 1
    Next
    Return $aOut
    EndIf
    EndFunc

    [/autoit]
    • Offizieller Beitrag

    Man kann es auch noch etwas kürzen, die Prüfung auf Dateityp und evtl. vorzeitiges Verlassen der Schleife bringt eigentlich keinen Vorteil:

    Spoiler anzeigen
    [autoit]

    Func _GetHighestVer(ByRef $a)
    Local $name, $ver
    Local $oFileVer = ObjCreate('Scripting.Dictionary')
    For $i = 1 To $a[0]
    $name = StringLeft($a[$i], StringInStr($a[$i], '.', 1, -1))
    $ver = StringTrimLeft($a[$i], StringInStr($a[$i], '.', 1, -1))
    If $oFileVer.Exists($name) Then
    If $ver > $oFileVer.Item($name) Then $oFileVer.Item($name) = $ver
    Else
    $oFileVer.Add($name, $ver)
    EndIf
    Next
    If $oFileVer.Count > 0 Then
    Local $aOut[$oFileVer.Count]
    Local $strKey, $colKeys = $oFileVer.Keys, $i = 0
    For $strKey In $colKeys
    $aOut[$i] = $strKey & $oFileVer.Item($strKey)
    $i += 1
    Next
    Return $aOut
    EndIf
    EndFunc

    [/autoit]
  • Hallo miteinander,

    ein Problem habe ich noch.
    Und zwar, wenn ich das Beispiel im ersten Beitrag um folgende Dateien erweitere:

    7777_0016.prt
    7777_0016.prt.1
    7777_0016.prt.9

    dann gibt die Funktion "_GetHighestVer" nicht das gewünschte Ergebnis wie im dritten Beitrag wieder.

    Macht es Sinn mit dieser Funktion "_ArrayNaturalSort " (Beitrag 11) zu arbeiten und somit evt. das Array "$aRead" zu sortieren und anschließend damit weiter zu arbeiten?

    2 Mal editiert, zuletzt von Joec33m (9. November 2011 um 20:14)

  • Hallo,

    ich habe das Problem gelöst.
    In der Code-Zeile 15 musste ich lediglich die Variable &Ver und $oFileVer.Item($Name)
    in eine "ganze Zahl" umwandeln.
    Durch die Änderungen zwischen 7-13 erkennt das Script nun auch Dateien ohne Versionsnummer bzw. Dateien mit der Versionsnummer "0".

    Spoiler anzeigen
    [autoit]


    Func _GetHighestVer(ByRef $a)
    Local $oFileVer = ObjCreate('Scripting.Dictionary')
    Local $Name
    Local $Ver
    Local $i
    For $i = 0 To UBound($a)-1
    If StringIsDigit (StringTrimLeft($a[$i], StringInStr($a[$i], '.', 1, -1))) Then
    $Name = StringLeft($a[$i], StringInStr($a[$i], '.', 1, -1)-1)
    $Ver = StringTrimLeft($a[$i], StringInStr($a[$i], '.', 1, -1))
    Else
    $Name = $a[$i]
    $Ver = ""
    EndIf
    If $oFileVer.Exists($Name) Then
    If Int($Ver) > Int($oFileVer.Item($Name)) Then $oFileVer.Item($Name) = $Ver
    Else
    $oFileVer.Add($Name, $Ver)
    EndIf
    Next
    If $oFileVer.Count > 0 Then
    Local $FileListHighestVer[$oFileVer.Count]
    Local $strKey, $colKeys = $oFileVer.Keys, $i = 0
    For $strKey In $colKeys
    $FileListHighestVer[$i] = $strKey & "." & $oFileVer.Item($strKey)
    $i += 1
    Next
    Return $FileListHighestVer
    EndIf
    EndFunc

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

    Func _ListMinusList (ByRef $a, $b)
    Local $i
    For $i = UBound($a) - 1 To 0 Step -1
    If _ArraySearch($b, $a[$i]) <> -1 Then _ArrayDelete($a, $i)
    Next
    Return $a
    EndFunc

    [/autoit]