
FlattenDir: a flexible directory flattener

pokeeffe
- Notes:
- The first argument is the name of an existing path as a string
- Windows users will need to place recycle.exe in their %windir%\system32 folder. It is available from MaDdoG software (http://www.maddogsw.com/) but is also attached to this post.
- Macintosh users will have to test the 'move to trash' functionality on their own - I don't have Mac access, sorry.
- Errors which prevent files/folders from being moved as expected will print to the command window but will not halt execution (I think); erroneous/missing paths will stop it
- Lots of informative debug statements will also print to the command window.
- There is NO UNDO!
// flattens file directories by recursively lifting contents out of subfolders Function FlattenDir( pathName, recurse, overwrite, [fileFilter, kill] ) string pathName // string name of existing path; use NewPath or Misc->New Path... variable recurse // how many levels to flatten? use -1 for ALL, 0 does nothing variable overwrite // nonzero to overwrite files with existing names string fileFilter // optional: provide filter to only lift certain file types // see <fileTypeOrExtStr> parameter from IndexedFile for OK formats // defaults to "????"=ALL FILES if format is not acceptable (no warnings!!) variable kill // optional: specify how subfolders are handled after flattening // negative #s: leave subfolder structure alone (flattens files only) // 0: emptied subfolders deleted only (default) // 1: all subfolders deleted (and remaining contents!!) // 2: do not delete any subfolders PathInfo $pathName If ( !V_flag ) print "FlattenDir: path <"+pathName+"> could not be found - aborting." return -1 endif GetFileFolderInfo/D/Q/Z S_path If ( V_flag ) print "FlattenDir: directory specified by path <"+pathName+"> could not be found - aborting." return -1 endif variable i, j, status string here = RemoveEnding(S_path,":"), folderList, filesIn, foldersIn, thisFile, thisFolder, tmpPN, subdir, delcmd If ( ParamIsDefault(fileFilter) || !GrepString(fileFilter, "^[.]{1}[a-zA-Z0-9]*$|^[a-zA-Z0-9]{4}$|^[?]{4}$") ) fileFilter = "????" // ensure fileFilter is an acceptable value endif if ( recurse ) // do nothing if no more recursive levels folderList = IndexedDir( $pathName, -1, 1 ) for (i=0; i<ItemsInList(folderList); i+=1) // for each subfolder found in here... subdir = StringFromList(i, folderList) tmpPN = UniqueName("TmpPath", 12, i) NewPath/Q/O $tmpPN, subdir // [positive <recurse> eventually stops at 0; negative <recurse> stops at no more subfolders] status = FlattenDir(tmpPN, (recurse-1), overwrite, fileFilter=fileFilter, kill=kill) // ...attempt to flatten it... if ( status ) return status endif filesIn = IndexedFile( $tmpPN, -1, fileFilter) // ...pull out all files matching filter... for (j=0; j<ItemsInList(filesIn); j+=1) thisFile = StringFromList(j, filesIn) try if (overwrite) MoveFile/D/O/Z (subdir+":"+thisFile) as here AbortOnValue V_flag, 1 else MoveFile/D/Z (subdir+":"+thisFile) as here If ( V_flag ) // print "SKIP FILE",thisFile,"BECAUSE NO OVERWRITE" // DEBUG endif // endif catch print "FlattenDir: could not move file <"+subdir+":"+thisFile+"> for unknown reason" endtry print "MOVE FILE",thisFile,"FROM",subdir,"TO",here // DEBUG endfor If ( kill < 0 ) KillPath $tmpPN continue // ...and skip the rest if ignoring subfolder structure. Otherwise endif foldersIn = IndexedDir( $tmpPN, -1, 1 ) // ...pull any subsubfolders out of this subfolder... for (j=0; j<ItemsInList(foldersIn); j+=1) thisFolder = StringFromList(j, foldersIn) try MoveFolder/D/Z thisFolder as here AbortOnValue V_flag, 1 print "MOVE DIR",thisFolder,"FROM",subdir,"TO",here // DEBUG catch print "FlattenDir: could not move folder <"+thisFolder+"> for unknown reason" endtry endfor switch (kill) // ... then... case 2: // ...do not delete this subfolder break default: case 0: // ...do not delete this subfolder if it has files in it If ( ItemsInList(IndexedFile($tmpPN, -1, "????")) ) print "SKIP DIR",subdir,"BECAUSE NOT EMPTY" // DEBUG break endif case 1: // ...delete this subfolder strswitch ( IgorInfo(2) ) case "Windows": try delcmd = "recycle.exe -f "+ParseFilePath(5, subdir, "\\", 0, 0) ExecuteScriptText/Z delcmd AbortOnValue V_flag, 1 print "RECYCLE DIR",subdir // DEBUG catch print "FlattenDir: could not recycle folder <"+subdir+"> for unknown reason" endtry break case "Macintosh": try // >> this block adapted from work by aclight via IgorExchange.com string posixPath = ParseFilePath(5, subdir, "/", 0, 0) if (strlen(posixPath) > 0) sprintf delcmd, "tell application \"Finder\" to move ((POSIX file \"%s\") as alias) to trash", posixPath ExecuteScriptText/Z delcmd AbortOnValue V_flag, 1 endif catch print "FlattenDir: could not move folder <"+subdir+"> to trash for unknown reason" endtry // << break endswitch endswitch KillPath $tmpPN endfor endif return 0 End

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More