How to have multiple file extensions in a parameter + minor improvements to my script Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
User avatar
SyntaxTerror
Posts: 23
Joined: 23 May 2017, 12:55

How to have multiple file extensions in a parameter + minor improvements to my script

09 Jun 2020, 10:04

Hello

I found a script to rename batches of files with a CSV file (can't remember where, it was long ago), but I'd like to improve it a bit and I'm afraid that my scripting skills are not sufficient enough:

Code: Select all

#NoEnv
#SingleInstance
SetWorkingDir %A_ScriptDir%
SetBatchLines, -1 ; At end of init set to 0.

; Settings
csv_file := "D:\Videos\New\titles.csv"    ; Database with the new file names.
source_folder := "D:\Videos\New"          ; Place of the source files.
destination_folder := "D:\Videos\New"     ; Where to copy the files.

/*
CSV file content is expected like this:

S01E01,S01E01 - First Episode
S01E02,S01E02 - Second Episode

File names in source folder are expected like this:

S01E01.avi
S01E01.avi
*/

; Setup Folders
FileSelectFile, csv_file, , %csv_file%, Which file contains the names?, CSV files (*.csv)
FileSelectFolder, source_folder, %source_folder%, 1, Where are the files?
FileSelectFolder, destination_folder, %destination_folder%, 1, Where to copy the files?
FileCreateDir, %destination_folder%

; Processing
Loop, Read, %csv_file%
{
    line := A_LoopReadLine		; A_LoopReadLine contains in example "S01E01,S01E01 - First Episode".
    Loop, Parse, line, CSV
    {
		title := RegExReplace(A_LoopReadLine, "^.*?,(.*)", "$1")							; Trims A_LoopReadLine to get only the title
        FileCopy, %source_folder%\%A_LoopField%.avi, %destination_folder%\%title%.avi, 1	; If A_Index is "1", then A_LoopField contains in example "S01E01".
		FileRecycle, %source_folder%\%A_LoopField%.avi										; Sends the source file to the recycle bin
        Break																				; First entry is needed, not more.
    }
}
1. I'd like to avoid to have to edit the script to change the file extension if it is not an .AVI (ie. I want this script to work for AVI, MP4, MKV, etc.).
Is there is a way to "collect" the extension and change it in the "FileCopy" command first and second parameters, as well as in the "FileRecycle" command? Obviously, it needs to be the same as the original file.
2. If a file name in the "titles.csv" has a "?", a ":", or any other character not allowed in file names, the file is not renamed (but the "FileRecycle" still erases the original file).
Is there is a way to avoid this, eg. detecting such characters and removing or replacing them, or at least sending an error message/not sending the file to the recycle bin?
3. It seems that this script doesn't recognise the values of the settings variable (csv_file, source_folder, destination_folder) and every time I launch the script, it asks where are the CSV file and the folder locations, so where does the problem comes from?

Thank you for your answers.
braunbaer
Posts: 84
Joined: 22 Feb 2016, 10:49

Re: How to have multiple file extensions in a parameter + minor improvements to my script

09 Jun 2020, 11:04

First, instead of filecopy and filerecycle, you should use filemove. The operation is much faster (if source and destination are on the same drive) and If the move fails for whatever reason, the original file is not touched.

Not yet tested, but this code should work. Every sequencce of non-allowed characters is replaced by a space character

Code: Select all

#NoEnv
#SingleInstance
SetWorkingDir %A_ScriptDir%
SetBatchLines, -1 ; At end of init set to 0.

; Settings
csv_file := "D:\Videos\New\titles.csv"    ; Database with the new file names.
source_folder := "D:\Videos\New"          ; Place of the source files.
destination_folder := "D:\Videos\New"     ; Where to copy the files.

/*
CSV file content is expected like this:

S01E01,S01E01 - First Episode
S01E02,S01E02 - Second Episode

File names in source folder are expected like this:

S01E01.avi
S01E01.avi
*/

; Setup Folders
; removed the question for name and folders

;FileSelectFile, csv_file, , %csv_file%, Which file contains the names?, CSV files (*.csv)
;FileSelectFolder, source_folder, %source_folder%, 1, Where are the files?
;FileSelectFolder, destination_folder, %destination_folder%, 1, Where to copy the files?

FileCreateDir, %destination_folder%

; Processing
Loop, Read, %csv_file%
     if regexMatch(A_LoopReadLine,  "^([^,]+),(.+)", Match")                    ; separe 1st and 2nd field in Match1 and Match2
     {
         name:=Match1, title:=regexreplace(Match2,"[\\/;:|?*<>]+"," ")          ; replace non allowed characters in title
         FileMove, %source_folder%\%name%.*, %destination_folder%\%title%.*, 1  ; move/rename file 	
         if (errorlevel)
              msgbox File %name% could not be moved to `n%destination_folder%\%title%
     }
     else 
         msgbox No valid filename or no title: %A_LoopReadline%
return
User avatar
SyntaxTerror
Posts: 23
Joined: 23 May 2017, 12:55

Re: How to have multiple file extensions in a parameter + minor improvements to my script

12 Jun 2020, 08:20

Hello braunbaer and thank you for your answer.

Unfortunately your script doesn't work, and it has a syntax error line 34 with Match".
I tried different things (Match, Match1, Match2, with or without quotes) to no avail.

I think that there is another problem with the encoding of the file: I have accents in my folder names (French keyboard) and I use Notepad++, but even though I'm saving in UTF-8, the accents are transformed by AHK (eg. é => é), though the text of the scripts stays fine.
I also have this problem with my CSV file (eg. S01E01 - Bon appétit is renamed as S01E01 Bon appétit).

By the way, I found back the original script: https://autohotkey.com/board/topic/51476-renaming-files-from-a-given-list/ (I modified it a bit).
gregster
Posts: 4946
Joined: 30 Sep 2013, 06:48

Re: How to have multiple file extensions in a parameter + minor improvements to my script

12 Jun 2020, 08:31

SyntaxTerror wrote:
12 Jun 2020, 08:20
but even though I'm saving in UTF-8, the accents are transformed by AHK (eg. é => é), though the text of the scripts stays fine.
to be clear: you need to save your script as UTF-8 with BOM, please compare https://www.autohotkey.com/docs/FAQ.htm#nonascii
User avatar
SyntaxTerror
Posts: 23
Joined: 23 May 2017, 12:55

Re: How to have multiple file extensions in a parameter + minor improvements to my script

14 Jun 2020, 04:50

gregster wrote:
12 Jun 2020, 08:31
to be clear: you need to save your script as UTF-8 with BOM, please compare https://www.autohotkey.com/docs/FAQ.htm#nonascii
Thanks gregster, it seems to work. I wasn't aware of the difference between UTF-8 and UTF-8 with BOM (and I'm still unsure of it :shifty:)
User avatar
SyntaxTerror
Posts: 23
Joined: 23 May 2017, 12:55

Re: How to have multiple file extensions in a parameter + minor improvements to my script  Topic is solved

14 Jun 2020, 06:38

I tinkered with the code a bit and got what I wanted.

Here is the edited code, that seems to work :

Code: Select all

#NoEnv
#SingleInstance
SetWorkingDir %A_ScriptDir%
SetBatchLines, -1 ; At end of init set to 0.

; Settings (disabled)
;csv_file := "D:\Vidéos\°Nouveau\°Récent\titres.csv"    ; Database with the new file names.
;source_folder := "D:\Vidéos\°Nouveau\°Récent"          ; Place of the source files.
;destination_folder := "D:\Vidéos\°Nouveau\°Récent"     ; Where to copy the files.

/*
CSV file content is expected like this:
S01E01,S01E01 - First Episode
S01E02,S01E02 - Second Episode

File names in source folder are expected like this (file types can be anything, even mixed)
S01E01.avi
S01E01.avi
*/

; Setup Folders
FileSelectFile, csv_file, , %csv_file%, Which file contains the names?, CSV files (*.csv)
FileSelectFolder, source_folder, %source_folder%, 1, Where are the files?
msgbox, 4, Rename Series, Use the same folder to copy the files?
IfMsgBox Yes
	destination_folder := source_folder
else
	{
	FileSelectFolder, destination_folder, %destination_folder%, 1, Where to copy the files?
	FileCreateDir, %destination_folder%
	}

; Processing
Loop, Read, %csv_file%
{
    line := A_LoopReadLine			; A_LoopReadLine contains e.g. "S01E01,S01E01 - First Episode".
    Loop, Parse, line, CSV
    {
		title := RegExReplace(A_LoopReadLine, "^.*?,(.*)", "$1")						; Trims A_LoopReadLine to get only the title
        title := regexreplace(title,"\s*[?]+","")										; Deletes "?" in the file name (unallowed character in file names)
        title := regexreplace(title,"\s*[;:]+",",")										; Replaces unallowed character ";:" by ","
        title := regexreplace(title,"[\\/|*<>]+","-")									; Replaces unallowed character "\/|*<>" by "-"
		FileMove, %source_folder%\%A_LoopField%.*, %destination_folder%\%title%.*, 1	; If A_Index is "1", then A_LoopField contains in example "S01E01".
        Break																			; First entry is needed, not more.
    }
}
It allows any file types, even mixed, deletes question marks, replaces unallowed characters by commas or hyphens.
It also deals with unwanted spaces potentially in front of question marks and colons/semi-colons present in titles in French.

Thanks to braunbaer and gregster for putting me on the path to the solution.
Using FileMove was a good idea, as it seems to be nearly instantaneous, and doesn't pose problems with full disk drives. :thumbup:

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], RubbeH and 54 guests