I’m in a rather unusual situation, and I’m hoping someone might be able to help me figure this out:
First, the environment
-Mac OS X Server 10.5.6 with a SMB fileshare mounted. (For reasons too complex to go into here, I don’t have console access to the windows machine providing the share.)
The problem
Many of the files that have been uploaded to the SMB fileshare have really strange filenames, namely ones that include characters like /, , and : in the name of an individual file. Yes, the file’s NAME might be something like “Dog/Cat tests.txt” or “2:30PM Interview.txt” or “Output from C:.txt”.
Our backup system doesn’t really like having characters which are often used as delimiters for FOLDERS in the name of individual FILES. (While it backs up the files, it changes the names as it does so, which would break other things if we ever had to recover those files.)
What I’m trying to do
So, I’m trying to generate a list of all the files that have those strange filenames, so we can go through and fix them.
What I’ve tried (all unsuccessful)
Doing a finder search by choosing “Find” from the “File” menu. (Unfortunately doesn’t seem to work on a SMB volume–I can find all the files with screwy names on my local disk quite easily, but not across the network to the SMB share.)
Writing an AppleScript that walks through the tree of the files/folders on the SMB volume and checks the name of each one individually using the “info for” command. (It runs incredibly slowly–we have several terabytes of fairly small files on the windows share–and it failed with an Apple Event timeout after having run for 36 or 40 hours.)
A unix command line that reads something like:
find . -exec osascript -e ‘tell application “Terminal” to display dialog name of file "’{}‘"’ ;
( I can’t seem to get the syntax right to have it do this, and I’m not sure if it would work even if I could, as it’s seeing things from the Unix point of view, not the MacOS point of view.)
Finally found a solution–it’s not exactly speedy (it still takes around 24 hours to run across our data), but at least it works:
set the_folder to choose folder with prompt "Please choose the folder to search for bad filenames in:" as string
tell application "Finder" to set defaultFolderName to name of (the_folder as alias)
set resultsFile to choose file name with prompt "Save results file as:" default name "Strange Filenames-" & defaultFolderName & ".txt" default location (path to desktop as alias)
set badFiles to ((current date) as string) & return & "File Name" & tab & "Path to file (Macintosh style)" & tab & "Path to file (Unix style)" & return
set filesToCheck to do shell script "find" & space & quoted form of POSIX path of the_folder & space & "-print"
set origDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set fileCheckList to text items of filesToCheck
set AppleScript's text item delimiters to origDelimiters
repeat with currFile in fileCheckList
-- display dialog currFile
try
set macFile to (POSIX file currFile)
set macFilePath to ((macFile as alias) as string)
--display dialog macFilePath
tell application "Finder" to set myFilename to name of (macFile as alias)
if ((myFilename as string) contains ":" or (myFilename as string) contains "/" or (myFilename as string) contains "|" or (myFilename as string) contains "\\") then
set badFiles to (badFiles & myFilename as string) & tab & macFilePath & tab & currFile & return
--display dialog "BAD FILE! (Mac)" & space & myFilename as string giving up after 1
end if
on error errText number errNum
set badFiles to badFiles & "ERROR NOT FOUND" & tab & tab & currFile & tab & errNum & space & errText & return
display dialog "BAD FILE! (Error)" & space & errNum & space & errText & return & currFile giving up after 10
end try
end repeat
write_to_file(badFiles, resultsFile, false)
on write_to_file(this_data, target_file, append_data)
try
set the target_file to the target_file as text
set the open_target_file to ¬
open for access file target_file with write permission
if append_data is false then ¬
set eof of the open_target_file to 0
write this_data to the open_target_file starting at eof
close access the open_target_file
return true
on error
try
close access file target_file
end try
display dialog "error writing to file!"
return false
end try
end write_to_file