// // File-Ren.vdm Christian Ziemski 10.08.2004 // // modified 06.09.2004 file-ren.syn and file-ren.txt are created if needed // // // Extended File Renaming Utility using regular expressions // //------------------------------------------------------------------ // // Register usage: // // 90 old filename // 91 new filename // 92 Search() function // 93 Replace() function // 99 optional error message // // 103 directory // 104 old filename (regular expression) // 105 new filename (regular expression) // // #90 answer from DI1() => main action // #91 Cursor position // #92 answer from DI1() => file overwrite // #93 longest line // // #103 option in DI_1 // #104 option in DI_1 // #105 option in DI_1 // #106 buffer number //------------------------------------------------------------------ Reg_Push(90,99) Num_Push(90,99) Reg_Empty(99) // for error message Reg_Set(103, CUR_DIR) if (#103>1) { #103=0 } if (#104>1) { #104=0 } if (#105>2) { #105=1 } #93=0 Call("CREATE_FILES") // create helper files if needed :START: repeat (ALL) { #90=Dialog_Input_1(103,"`Extended File Renaming Utility`, `This utility lets you rename files using sophisticated search+replace expressions.`, `Note: You can't use DOS/Windows wildcards here! The macro uses 'Regular Expressions'. If you aren't familiar with RegExp, please use the [Help] below. `, ` [Examples] opens an user-editable file with some example expressions.`, ` [Test] only lists the directory showing the planned renamings and reopens this dialog. `, `|@(99)`, `.i??Directory: `, ` `,`.h[] Select files case-sensitive`, `??Select files:`, `??Rename to:`, ` `,`.h[] Force the renaming to`, `.h() lower or`, `.h() UPPER case`, ` `, `[&Rename]`,`.b[&Test]`,`[&Cancel]`,`[&Help]`,`[&Examples]`", SET+SCREEN+CENTER,0,0) if ((#90==3) || (#90==0)) { Num_Pop(90,99) Reg_Pop(90,99) return } else { if (#90==4) { Help("Regular expressions") Continue } } if (#90==5) { File_Open("|(USER_MACRO)\file-ren.txt") Num_Pop(90,99) Reg_Pop(90,99) return } Reg_Empty(99) // for error message if ( ! File_Exist("|@(103)\nul", NOERR) ) { Reg_Set(99, " Error: Directory doesn't exist! ") Continue } if (#90==1) { // check filenames if real run if ((Reg_Size(104)==0) || ((Reg_Size(105)==0)) && (#104==0)) { Reg_Set(99, " *** Error: Filename(s) missing! Or 'Force .. to .. case' not set.*** ") Continue } } Break // else leave loop } // Prepare the search and replace commands Reg_Set(92,`Search_Block("^`) Reg_Set(92, @104, APPEND) Reg_Set(92, `$", Cur_Pos, EoL_Pos, REGEXP+NOERR`, APPEND) if (#103==0) { Reg_Set(92, `)`, APPEND) } else { Reg_Set(92, `+CASE)`, APPEND) } Reg_Set(93, `Replace_Block("`) Reg_Set(93, @104, APPEND) Reg_Set(93, `","`, APPEND) Reg_Set(93, @105, APPEND) Reg_Set(93, `", Cur_Pos, EoL_Pos, REGEXP+NOERR)`, APPEND) ChDir("|@(103)") // change into choosen data directory // Open a temporary working file and empty it if needed File_Open("|(VEDIT_TEMP)\file-ren.tmp", NOMSG+NOEVENT) Del_Block(0, File_Size) Config(PG_E_SYNTAX, "Enable syntax highlighting (*)", 1, LOCAL) Syntax_Load("file-ren.syn") // do a directory listing and redirect it into the current file Out_Ins() Dir("*.*", NOMSG+SUPPRESS+NOERR) Out_Ins(CLEAR) // get longest line Begin_Of_File while ( ! At_EoF ) { EoL #93=Max(#93, Cur_Col) Line(1) } // process the directory listing Begin_Of_File while ( ! At_EoF ) { if (Reg_Size(104)>0) { Begin_Of_Line Call(92) // search within line if ( ! Error_Match) { // if found Reg_Copy_Block(90, BoL_Pos, EoL_Pos) // remember original filename if (Reg_Size(104)>0) { if ((Reg_Size(105)>0) || (#104==1)) { End_Of_Line Ins_Indent(#93+4) Ins_Text("-> ") Reg_Ins(90, BEGIN) #91=Cur_Pos if (Reg_Size(105)>0) { Call(93) // replace old name by new name Goto_Pos(#91) } if (#104==1) { if (#105==1) { Case_Lower_Block(Cur_Pos, EoL_Pos) } else { Case_Upper_Block(Cur_Pos, EoL_Pos) } } } } Reg_Copy_Block(91, Cur_Pos, EoL_Pos) // do it ... if (#90==1) { #92=2 if (Reg_Size(105)>0) { // if there is a real renaming (and not only case switching): Reg_Set(103, @91) // check for existing target file while (File_Exist("|@(103)")) { #92=Dialog_Input_1(103,"`Extended File Renaming Utility`, `Problem: The file |@(90) should be renamed to the already `, `??existing file`, `You can change the target name in the input field.`, `[&Try again]`, `[&Force]`,`[Do&n't touch]`", SET+SCREEN+CENTER,0,0) if (((#92==1) || (#92==2)) && (Reg_Size(103)==0)) { Continue } Reg_Set(91, @103) if (#92!=1) { break } #92=2 } } if (#92==2) { if (Reg_Compare(90, @(91))==0) { // workaround for File_Rename bug! File_Rename("|@(90)", "file-ren|(PID)", OK) File_Rename("file-ren|(PID)", "|@(91)", OK) } else { File_Rename("|@(90)", "|@(91)", OK) } } } } } Line(1) // next line in listing } File_Save(NOMSG+BEGIN) if (#90==1) { // if not in "test" mode Buf_Quit(OK) File_Delete("|(VEDIT_TEMP)\file-ren.tmp", OK) } else { Search("-> ", NOERR) if (! Error_Match) { Set_Visual_Line(3) } Update goto START } Num_Pop(90,99) Reg_Pop(90,99) File_Delete("|(USER_MACRO)\file-ren.syn", NOERR) return //============================================================================= :CREATE_FILES: // Create Syntax-Highlighting file in USER_MACRO if it doesn't already exist if (! (File_Exist("|(USER_MACRO)\file-ren.syn") || File_Exist("|(HOME)\file-ren.syn"))) { #106=Buf_Num Buf_Switch(Buf_Free) Ins_Text(`// VEDIT syntax highlighting definition for FILE-REN.VDM Reserved2 = "->|*" `) File_Save_As("|(USER_MACRO)\file-ren.syn", OK+NOMSG) Buf_Quit(OK) Buf_Switch(#106) } // Create Example file in USER_MACRO if it doesn't already exist if (! File_Exist("|(USER_MACRO)\file-ren.txt")) { #106=Buf_Num Buf_Switch(Buf_Free) Ins_Text(` Since Regular Expressions may be a bit complicated it may help to have some examples for usage with FILE-REN.VDM. 1) Renaming all .txt files to .doc files Old name: {.*}.txt New name: \1.doc 2) Renaming all .txt files to .doc files with additional name modification. The leading text "test" should be renamed to "prod" Old name: test{.*}.txt New name: prod\1.doc 3) Files named like abc567.txt should be renamed to DATA-567.abc Old name: {[a-z]+}{[0-9]+}.txt New name: DATA-\2.\1 4) Add an additional digit to numbered files (Patrick Carroll's task) Old name: {.* }{[0-9][0-9]}{[we]_}{.*}.jpg New name: \10\2\3\4.jpg Example: IL03 016s 10w_001.jpg --> IL03 016s 010w_001.jpg IL03 025n 015e_001.jpg (untouched) 5) to be continued ... `) File_Save_As("|(USER_MACRO)\file-ren.txt", OK+NOMSG) Buf_Quit(OK) Buf_Switch(#106) } return