Jump to content

Recommended Posts

Posted

Long time lurker and first time poster here. I have gotten invaluable help from this forums archives and really appreciate it.  So I have a ton of music files and many have unneeded information in the filenames. Example 'Eagles - Hotel California(live).mp3' On my players display that song is already in the 'Eagles' folder so 'Eagles - ' in the title just eats display space. So instead of taking hours to manually rename files I spent hours on the following code. It's a work in progress and works for the most part. I ran into trouble when a file name would be '02 - Eagles - Hotel California(live).mp3' in that the line StringSplit($aFileList[$i], $delimStr, $STR_ENTIRESPLIT)[2] and subsequent FileMove would give me a file name of 'Eagles' since there were two instances of my $delimStr of ' - ' (space dash space) I was using. Any suggestions on easy way to avoid this?  Thanks in advance..
Here is the code so far.. Hope I am doing this right.

 

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.10.2
 Author:         on_jon     10/18/2017

 file_ren.au3
 Script Function:
    Rename all files in a user selected directory using delimiter criteria input by user.
    Renames files from right of delimiter entered.

    Future add options to rename from left and just remove characters.
    ToDo: Remove leading space if exists in new name.
    Option to recurse sub-directories


#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here



;;============================================================================================================

#include <File.au3>
#include <Array.au3>
#include <Misc.au3>
#include <StringConstants.au3>
#include <MsgBoxConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>


;;-------------------------------

Local $delimStr = ""
Local $fileDir, $browse, $cnt

;;-------------------------------

$RenFilesForm = GUICreate("Rename Files", 415, 198, 192, 125)
$delimInput = GUICtrlCreateInput("", 93, 18, 230, 21)
$infLabel = GUICtrlCreateLabel("Enter a string above where to split file names from and browse to a file/location. Will rename all candidate files to the right of string you enter. Note: spaces are OK - ", 106, 48, 200, 79)
GUICtrlSetFont(-1, 9, 500, 0, "Segoe UI")
GUISetBkColor(0xFFFFFF)
$BrowseBtn = GUICtrlCreateButton("Browse", 96, 152, 58, 25)
$RenameBtn = GUICtrlCreateButton("Rename", 184, 152, 58, 25)
$CancelBtn = GUICtrlCreateButton("Cancel", 264, 152, 58, 25)
; disable the Rename button until we know we have a delim value and location
GUICtrlSetState($RenameBtn, $GUI_DISABLE)
GUICtrlSetState($delimInput, $GUI_FOCUS)

GUISetState(@SW_SHOW)


While 1
$gMsg = GUIGetMsg()

Switch $gMsg

    Case $BrowseBtn

        Local $browse = FileOpenDialog("Select a file and we will check all files at that location", @ScriptDir, "All (*.*)", 1 + 2,@ScriptName)
        If @error Then
            MsgBox(0, "Error", "No File/location chosen")
        Else
            $fileDir = StringRegExpReplace($browse, "\\[^\\]+$", "")

        EndIf

        Sleep (3000)

        $delimStr = GUICtrlRead($delimInput)

        ; better way to do this?
        While $delimStr = ""

            $cnt = $cnt + 1
            If $cnt > 12 Then Exit
            MsgBox(0, "Error", "No search string entered. Please enter something in the input field.")
            Sleep (10000)
            $delimStr = GUICtrlRead($delimInput)

        WEnd

        ;format the delim string to add wildcard
        Local $delimStr2 = "*" & $delimStr & "*"
        GUICtrlSetState($RenameBtn, $GUI_ENABLE)
        GUICtrlSetState($RenameBtn, $GUI_FOCUS)
        ;MsgBox(0, "Info - Debug", "Location to search for files with '" & $delimStr2 & "' in name is " & $fileDir )


    Case $RenameBtn

        If StringLen($delimStr) = 0 Or StringLen($fileDir) = 0 Then
            MsgBox(0,"Error", "Please Browse to Something and/or enter a valid string")
        Else

            Local $aFileList = _FileListToArray($fileDir, $delimStr2, 1)

            ;_ArrayDisplay($aFileList, "File List")

            If IsArray($aFileList) then ConsoleWrite("Number of rename candidate files returned = " & $aFileList[0] & @LF)

                If Not IsArray($aFileList) then
                    MsgBox(0, "Error", "No rename candidate files found.")
                    Exit
                EndIf

                If @error = 1 Then
                    MsgBox(0, "Error", "The folder was not found.")
                    Exit
                EndIf

                If @error = 4 Then
                    MsgBox(0, "Error", "No files found to rename.")
                    Exit
                EndIf

                $fileDir = $fileDir & "\"

                For $i = 1 to UBound($aFileList) -1      ; 0 is the file count

                    Local $aFileName = StringSplit($aFileList[$i], $delimStr, $STR_ENTIRESPLIT)[2]

                    ConsoleWrite("Renamed file = " & $fileDir & $aFileName & @LF)
                    FileMove($fileDir & $aFileList[$i], $fileDir & $aFileName)

                Next

        EndIf

    Case $GUI_EVENT_CLOSE, $CancelBtn
        Exit

EndSwitch

WEnd

 

Posted

?

try changing

Local $aFileName = StringSplit($aFileList[$i], $delimStr, $STR_ENTIRESPLIT)[2]

to

Local $aFileName = StringSplit($aFileList[$i], $delimStr, $STR_ENTIRESPLIT) ; ... better to declare Local $aFileName outside the loop ...
$aFileName = $aFileName[$aFileName[0]] ; better to use another variable name here! ( i.e. $sFileName = ...)

p.s. not tested

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Posted

Thanks Chimp, that did the trick. Not sure how I can 'declare Local $aFileName outside the loop' when it is applied to the array? Excuse my ignorance but the part of my brain for fully understanding arrays seems to be dead :'(. I declared Local $aFileName and $sFileName (nul) at the top of the script. Here is the updated script that tested good.
 

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.10.2
 Author:         on_jon     10/18/2017

 file_ren.au3
 Script Function:
    Rename all files in a user selected directory using delimiter criteria input by user.
    Renames files from right of delimiter entered.

    Future add options to rename from left and just remove characters.
    ToDo: Remove leading space if exists in new name.
    Option to recurse sub-directories


#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here



;;============================================================================================================

#include <File.au3>
#include <Array.au3>
#include <Misc.au3>
#include <StringConstants.au3>
#include <MsgBoxConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>


;;-------------------------------

Local $delimStr = ""
Local $fileDir, $browse, $cnt, $aFileName, $sFileName

;;-------------------------------

$RenFilesForm = GUICreate("Rename Files", 415, 198, 192, 125)
$delimInput = GUICtrlCreateInput("", 93, 18, 230, 21)
$infLabel = GUICtrlCreateLabel("Enter a string above where to split file names from and browse to a file/location. Will rename all candidate files to the right of string you enter. Note: spaces are OK - ", 106, 48, 200, 79)
GUICtrlSetFont(-1, 9, 500, 0, "Segoe UI")
GUISetBkColor(0xFFFFFF)
$BrowseBtn = GUICtrlCreateButton("Browse", 96, 152, 58, 25)
$RenameBtn = GUICtrlCreateButton("Rename", 184, 152, 58, 25)
$CancelBtn = GUICtrlCreateButton("Cancel", 264, 152, 58, 25)
; disable the Rename button until we know we have a delim value and location
GUICtrlSetState($RenameBtn, $GUI_DISABLE)
GUICtrlSetState($delimInput, $GUI_FOCUS)

GUISetState(@SW_SHOW)


While 1
$gMsg = GUIGetMsg()

Switch $gMsg

    Case $BrowseBtn

        Local $browse = FileOpenDialog("Select a file and we will check all files at that location", @ScriptDir, "All (*.*)", 1 + 2,@ScriptName)
        If @error Then
            MsgBox(0, "Error", "No File/location chosen")
        Else
            $fileDir = StringRegExpReplace($browse, "\\[^\\]+$", "")

        EndIf

        Sleep (2000)

        $delimStr = GUICtrlRead($delimInput)

        ; better way to do this?
        While $delimStr = ""

            $cnt = $cnt + 1
            If $cnt > 12 Then Exit
            MsgBox(0, "Error", "No search string entered. Please enter something in the input field.")
            Sleep (10000)
            $delimStr = GUICtrlRead($delimInput)

        WEnd

        ;format the delim string to add wildcard for FileListToArray usage
        Local $delimStr2 = "*" & $delimStr & "*"
        GUICtrlSetState($RenameBtn, $GUI_ENABLE)
        GUICtrlSetState($RenameBtn, $GUI_FOCUS)
        ;MsgBox(0, "Info - Debug", "Location to search for files with '" & $delimStr2 & "' in name is " & $fileDir )


    Case $RenameBtn

        If StringLen($delimStr) = 0 Or StringLen($fileDir) = 0 Then
            MsgBox(0,"Error", "Please Browse to Something and/or enter a valid string")
        Else

            Local $aFileList = _FileListToArray($fileDir, $delimStr2, 1)

            ;_ArrayDisplay($aFileList, "File List")

            If IsArray($aFileList) then ConsoleWrite("Number of rename candidate files returned = " & $aFileList[0] & @LF)

                If Not IsArray($aFileList) then
                    MsgBox(0, "Error", "No rename candidate files found.")
                    Exit
                EndIf

                If @error = 1 Then
                    MsgBox(0, "Error", "The folder was not found.")
                    Exit
                EndIf

                If @error = 4 Then
                    MsgBox(0, "Error", "No files found to rename.")
                    Exit
                EndIf

                $fileDir = $fileDir & "\"

                For $i = 1 to UBound($aFileList) -1      ; 0 is the file count

                    ;Local $aFileName = StringSplit($aFileList[$i], $delimStr, $STR_ENTIRESPLIT)[2] ;< this caused issues when 2 instances of delim string were in name
                    $aFileName = StringSplit($aFileList[$i], $delimStr, $STR_ENTIRESPLIT) ; ... better to declare Local $aFileName outside the loop ...?? ; per Chimp on autoIT forum
                    $sFileName = $aFileName[$aFileName[0]] ; better to use another variable name here! ( i.e. $sFileName = ...) ; per Chimp on autoIT forum

                    ConsoleWrite("Renamed file = " & $fileDir & $sFileName & @LF)
                    FileMove($fileDir & $aFileList[$i], $fileDir & $sFileName)

                Next

        EndIf

    Case $GUI_EVENT_CLOSE, $CancelBtn
        Exit

EndSwitch

WEnd

 

Posted

The ability to declare outside the loop relates to the scope of variables.  The scope dictates where/how they can be used in your script (see help file on this - loops don't impact this though functions may).  It is not limited by the fact that you are using the variable as part of a filename referenced in an array.  Based on your response you may also want to take a look at the array section as well.  "An Array is [just] a variable containing a series of data elements".   Does that help?

Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...