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
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