Newbie Here...Would Appreciate Some Help With a Finder Script...

Hello.

Hopefully you wanted a unique list of the folders pathnames. :slight_smile:

set folderTarget to path to documents folder
script o
	property allPaths : missing value
	property folderPaths : missing value
end script

set astid to AppleScript's text item delimiters
-- Get the paths to all the files in the chosen hierarchy.
tell application "Finder" to set allPaths of o to (files of entire contents of folderTarget as alias list)

set {pxList, formerPaths} to {{}, {}}
set AppleScript's text item delimiters to "/"
set firstPath to (text items 1 thru -2 of (POSIX path of item 1 of allPaths of o)) as text
set {end of formerPaths, end of pxList} to {firstPath, firstPath}

repeat with i from 2 to count allPaths of o
	set thisPath to (text items 1 thru -2 of (POSIX path of item i of allPaths of o)) as text
	if thisPath is not in formerPaths then
		set end of pxList to thisPath
		set end of formerPaths to thisPath
	end if
end repeat
set AppleScript's text item delimiters to astid
set o's folderPaths to pxList
return pxList

I actually wanted a list that was “integrated” in the same list with the files… :frowning:

Not to worry, I will take a look at your above code to see whether I can make it work…thanks!

Hi JoelC.

I’m afraid I haven’t been following this topic very closely and have rather lost track of what it’s trying to achieve. I posted my ‘entire contents’ script because it produces HFS paths quite quickly, which at the time were what I thought you wanted.

The Finder’s ‘entire contents’ action is usually pretty slow ” especially when there’s a large number of items in the hierarchy. But if the result’s returned ‘as text’, it’s usually a lot faster. (Text is a simpler form of data to put together and return to the script than is an alias list or a list of Finder references.) However, it’s still not as fast as a “find” shell script and it only returns HFS paths. It’s easy to derive POSIX paths individually from the HFS ones later later, but that adds still more to the time taken.

Of course, if the object’s to just test the lengths of the paths, then strictly speaking, there’s no need to convert them. If the root folder’s on the startup volume, you know that all the HFS paths are longer than the corresponding POSIX paths by the length of the startup volume’s name, so you just need to increase the maximum allowable length by that much. However, you do have to remember that HFS directory paths (as returned by the Finder) end with colons, whereas the corresponding POSIX paths (as returned by find) don’t. (By the way, find inserts its own slash between the path to the root folder and the rest of the path to a found item. So if the input path ends with a slash, as in the shell scripts earlier in this thread, there’ll be an extra slash at that point in all the found paths.)

Appreciated and understood the rational for the use of ‘as text’.

Hopefully I have enough to help me get over the hump so I can complete this script and move on to the next!

Yes, I discovered this on my own [i.e. the insertion of the additional ‘/’] and have remedied the situation.

Hello.

Not entirely sure about what you mean by “intergrate”, but I mocked up a script that returns the folder path side by side with the file path. You can juggle it a little by commenting out, and commenting in some lines, if you prefer a text version. I hope this suits you, one way or another.

set folderTarget to path to documents folder
script o
	property allPaths : missing value
	property folderPaths : missing value
end script

set astid to AppleScript's text item delimiters
-- Get the paths to all the files in the chosen hierarchy.
tell application "Finder" to set allPaths of o to (files of entire contents of folderTarget as alias list)

set AppleScript's text item delimiters to "/"
set pxList to {}
# set pxList to "" if you are going for the text version for
repeat with i from 1 to count allPaths of o
	set thisFile to POSIX path of item i of allPaths of o
	set end of pxList to {thisFile, ((text items 1 thru -2 of thisFile) as text)}
	# the above returns a list consisting of path to file, and another item having paths to its folder
	# aka item 1 of item i of pxList and item 2 of item i of pxList 
	#
	#	set end of pxList to thisFile & ", " & ((text items 1 thru -2 of thisFile) as text) & linefeed
	# the above returns a comma separated list of full path name to file, and the pathname of its folder
end repeat
set AppleScript's text item delimiters to astid
set o's folderPaths to pxList
return pxList

A few housekeeping items to start things off.

  1. A huge thanks to everyone’s assistance and time spent helping me…although it has been tough slogging I do think that I am – thanks to all of you help – getting better at this.

  2. As a result of all the help that everyone has provided – both today and in the past – I feel the need to keep the dialog going so have worked diligently on my script [i.e. at least the “file and folder identification” portion].

  3. As far as methodology is concerned I have landed on the following approach:

a) I am identifying the list of all files [thanks to Nigel for pointing me in the right direction] without the use of the find command;

b) I am identifying the list of all folders [thanks to McUsrll for further pointing me in the right direction] without the use of the find command;

c) I am providing the user with the option of working with the HFS file format or the POSIX file format.

  1. The resulting script is as follows:

-- set the parameters / variables
set allPaths to {} -- The list of all files in HFS format
set allPathsPX to {} -- The list of all files in POSIX format
set theList to {} -- The list of all files whose pathname > maxCount in HFS format
set theListPX to {} -- The list of all files whole pathname > maxCount in POSIX format

set firstPath to {} -- The temporary holder for the "current index -1" folder
set secondPath to {} -- The temporary holder for the "current index" folder
set allPathsFolder to {} -- The list of all folders in HFS format
set allPathsFolderPX to {} -- The list of all folders in POSIX format

set maxCount to 200 -- As a temporary / testing maxCount

set FolderTarget to (choose folder with prompt "Choose the disk / directory / folder whose file lengths' will be compared against maxCount" default location (path to documents folder))


-- Get the pathnames of all the files in the chosen disk / directory / folder
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to linefeed
tell application "Finder" to set allPaths to text items of (files of entire contents of FolderTarget as text)


-- Get the pathnames of all the folders (as opposod to "files") in the chosen disk / directory / folder
set AppleScript's text item delimiters to ":"

repeat with i from 1 to count allPaths
	if ((i = 1) is true) then
		set firstPath to (text items 1 through -2 of item i of allPaths)
		set secondPath to (text items 1 through -2 of item i of allPaths)
		set end of allPathsFolder to firstPath
	end if
	
	if ((i > 1) is true) then
		set secondPath to (text items 1 through -2 of item i of allPaths) -- Get the folder pathname of the next file
		
		if ((firstPath is not equal to secondPath) is true) then -- The folder pathname of the next file differs from the folder pathname of the current file
			
			****if (((text items 1 through -2 of firstPath) is not equal to (text items 1 through -2 of secondPath)) is true) then -- Test whether a nested (next level) folder exists
				set allreadyThere to false -- Test whether the nested (next level) folder previously noted
				repeat with j from 1 to count allPathsFolder
					if (((text items 1 through -2 of secondPath as text) = item j of allPathsFolder as text) is true) then set allreadyThere to true
				end repeat
				
				if allreadyThere is false then set end of allPathsFolder to (text items 1 through -2 of secondPath)
				
				set end of allPathsFolder to secondPath
				set firstPath to secondPath****
				
			else
				
				set end of allPathsFolder to secondPath
				set firstPath to secondPath
				
			end if
		end if
	end if
end repeat


-- Provide the user with the option of using the HFS or POSIX file format
display dialog "Are the filename lengths being tested in HFS or POSIX file format?" buttons {"HFS", "POSIX"} default button 2 with icon note
set fileFormat to button returned of result

if ((fileFormat = "POSIX") is true) then
	repeat with k from 1 to count allPaths
		set end of allPathsPX to POSIX path of item k of allPaths
	end repeat
	repeat with k from 1 to count allPathsFolder
		set end of allPathsFolderPX to POSIX path of ((item k of allPathsFolder as text) & ":")
	end repeat
end if

if ((fileFormat = "POSIX") is true) then
	set allPaths to {}
	set allPathsFolder to {}
	repeat with l from 1 to count allPathsPX
		set end of allPaths to item l of allPathsPX
	end repeat
	repeat with l from 1 to count allPathsFolderPX
		set end of allPathsFolder to item l of allPathsFolderPX
	end repeat
end if

-- Test that all files and folders were processed
log "Total files are " & (count of allPaths)
log "Total folders are " & (count of allPathsFolder)
log "Total files and folders to compare to finder are " & ((count of allPaths) + (count of allPathsFolder) + 1) -- The 1 is for the parent folder


-- Reset / return AppleScript's text item delimiter to its original value
set AppleScript's text item delimiters to astid

-- Create the list of files whose pathname > maxCount and return the list
repeat with n from 1 to (count allPaths)
	set thisPath to item n of allPaths
	if ((count thisPath) > maxCount) then set end of theList to thisPath -- as alias
end repeat

return theList

  1. The resulting script is – because I am new to scripting – not as efficient, elegant or as short as possible but it “more or less works”.

  2. The script was more complicated to code than suggested in the previous posts because of “nested” / “next level” folders that contained only folders [i.e. no files]. The script – without the portion which is contained within the **** – was not identifying folders that contained only folders [no files].

When I run the script on most of disks /directories / folders that I tested I do get the proper number of files and folders reported [i.e. script metrics match finder metrics]…when I run the script on a heavily nested folder I no longer get the proper number of files and folders reported [i.e. script metrics do NOT match finder metrics]…when, for example, I ran the script on the Documents folder the script reports 33,451 total files and folders while Finder reports 33,660 for a difference of 290.

Would appreciate any assistance / insights people have to help me fix this.

Thanks.

PS. Next and hopefully the final step will occur tomorrow when I fix the Excel portion of the coding…I will then post the script for all to see / use / etc.!

Hi,

this is a version using find which is a bit faster (even with two shell calls)


script o
	property filePaths : ""
	property folderPaths : ""
end script

set maxCount to 80 -- As a temporary / testing maxCount
set theList to {} -- The list of all files whose pathname > maxCount 

set FolderTarget to POSIX path of (choose folder with prompt "Choose the disk / directory / folder whose file lengths' will be compared against maxCount" default location (path to documents folder))

set o's folderPaths to paragraphs of (do shell script "/usr/bin/find " & quoted form of FolderTarget & " -type d")
set o's filePaths to paragraphs of (do shell script "/usr/bin/find " & quoted form of FolderTarget & " -type f ! -type l ! -name '.*'")
display dialog "Are the filename lengths being tested in HFS or POSIX file format?" buttons {"HFS", "POSIX"} default button 2 with icon note
set fileFormat to button returned of result
if fileFormat = "POSIX" then
	
	repeat with aPath in o's filePaths
		if (length of aPath) > maxCount then set end of theList to contents of aPath -- as alias
	end repeat
else
	repeat with aPath in o's filePaths
		set HFSPath to POSIX file aPath as text
		if (length of HFSPath) > maxCount then set end of theList to HFSPath -- as alias
	end repeat
end if

log "Total files are " & (count of o's filePaths)
log "Total folders are " & (count of o's folderPaths)
log "Total files and folders to compare to finder are " & ((count of o's filePaths) + (count of o's folderPaths) + 1) -- The 1 is for the parent folder

return theList

Stefan:

Appreciate the script and will look at it later in the day…amazing how a few lines of code with two shell calls can replicate the much longer and and more involved code that I wrote.

I still need / want to figure out / fix my code for the additional nested folders to get it working!

Thanks.

Joel

A quick update to those following this thread…I have been working on the script today by doing some database / spreadsheet work to confirm that the script is picking up all the files and folders [not to mention, while I am at it, learning and identifying the “extra” files that the find command picks up]…this is an arduous task given I have progressed to larger and larger folders and am now using my DOCUMENTS folder which has 35,000+ files and folders.

I will be back in another day or two with the results and, to the extent that anyone is interested, I will publish the Access database / Excel spreadsheet that I am using.

Stay tuned and thanks!

Joel,

You asked about the path limit and how it is calculated. Running this should give you the answer, at least for HFS+:

use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"

set deskPath to POSIX path of (path to desktop)
set deskPathLength to length of deskPath
set folderPath to current application's NSString's stringWithString:deskPath
-- create nested folders to build long path
set folderName to "123456789a123456789b123456789c123456789d" -- 40 chars
set theNSFileManager to current application's NSFileManager's defaultManager()
repeat 24 times
	set folderPath to folderPath's stringByAppendingPathComponent:folderName
	theNSFileManager's createDirectoryAtPath:folderPath withIntermediateDirectories:true attributes:(missing value) |error|:(missing value)
end repeat
-- path should be 24 * 40 + desktop path characters -- say ~ 960-plus
set folderPathLength to folderPath's |length|()
-- save a file called "a" to the deepest folder
set dummyNSString to current application's NSString's stringWithString:"some text"
set filePath to folderPath's stringByAppendingPathComponent:"a"
dummyNSString's writeToFile:filePath atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
-- keep renaming the file by adding an extra character to the name, until it fails
repeat
	set filePathNew to filePath's stringByAppendingString:"a"
	set theLength to filePath's |length|()
	theNSFileManager's removeItemAtPath:filePathNew |error|:(missing value)
	set theResult to (theNSFileManager's moveItemAtPath:filePath toPath:filePathNew |error|:(missing value))
	if theResult as boolean is false then
		display dialog "Failed at " & theLength & " characters. Last file name is " & (theLength - folderPathLength) & " characters. Path to desktop is " & deskPathLength & " characters."
		exit repeat
	end if
	set filePath to filePathNew
end repeat

On my Mac, I get: “Failed at 1023 characters. Last file name is 19 characters. Path to desktop is 21 characters.” I tried modifying the number of intermediate folders, but it made no difference.

I also tried changing from path to desktop to a non-start-up HFS+ volume at “/Volumes/Extra”. The result then was:“Failed at 1023 characters. Last file name is 25 characters. Path to desktop is 14 characters.”

So it appears the limit is 1022 characters, and it includes all slashes in a POSIX file. But if any of the characters are non-ASCII, the limit decresaes (so it’s actually 1022 bytes).

Shane:

Thank you for this…it is interesting how much more robust OS X is than windows which I know from experience has a pathname limit of 255.

Joel

I edited Shane’s script to use folderNames of 50 characters.
I got :
“Failed at 1251 characters. Last file name is 2 characters. Path to desktop is 26 characters.”

I’m puzzled by the result of two added log instructions.
(1)
log folderPath
→ («class ocid» id «data optr0000000020C8F85AC87F0000»)
set folderPathLength to folderPath’s |length|()

(2) set filePath to filePathNew
end repeat
log filePath
→ («class ocid» id «data optr00000000A0C8F85AC87F0000»)

I was assuming that they would return POSIX paths.

The longer folder path was :
“/Users/yvankoenig/Desktop/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/”
which is 995 characters long

So it appears that somewhere, the script tried to create some complementary folders but failed silently.
In fact, it created only 19 folders.
Interesting to see that using ASObjC code may hit erroneous status without issuing an error. I triple checked, no try - on try block in the script able to explain this behavior.
When I tried to drop a file in the late subfolder I got an error number -8058 which I was unaware of what it means.
I tried to drop a file with a shorter name and it worked so the error was probably saying that I was trying to build a too long path.
In fact, I was able to rename the file as “123456789012345678901234.rtf”
which gave a full POSIX path of 1023 characters.

Nothing new for the limit but I thought that it may be interesting to point the fact that with ASObjC we may issue an error which is not reported giving odd results.

Yvan KOENIG (VALLAURIS, France) vendredi 12 décembre 2014 17:00:44

Yvan,

filePath and folderPath are Cocoa strings, you have to coerce them to AS strings, for example


log folderPath as text

Thank you Stefan.

With the correct log instructions, I got :
(1)
(/Users/yvankoenig/Desktop/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e)
Which is the string built but not the path really created.

(2)
“/Users/yvankoenig/Desktop/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/123456789a123456789b123456789c123456789d123456789e/a”
Which is not the really created path.

Yvan KOENIG (VALLAURIS, France) vendredi 12 décembre 2014 17:14:05

And what would today be without an update, so here goes…

But first a few house keeping items:

  1. I use the term “AppleScript” to refer to the script in post #38 of this thread…a big thank you to Nigel who wrote the “file” portion of the script.

  2. I use the term “Find Command” to refer to the script in post #39 of this thread…a big thank you to StefanK for who wrote the two “find” command shell scripts.

  3. I wanted to make sure that the final script was working fully and properly so I compared and tested the results of the two scripts against the actual number of files and number of folders per Finder [note: I manually counted a few of the smaller folder / subfolders to confirm and understand the results of Finder’s Get Info command].

  4. Test Results-Folders Without Deeply Nested Sub-Folders: Both scripts produced correct results.

  5. Test Results-Folders With Deeply Nested Sub-Folders: The test results are posted https://www.dropbox.com/s/v9ikzt1ss8jalw7/20141211_script%20to%20identify%20files%20and%20folders%20from%20a%20specified%20directory_test.pdf?dl=0 .

The key observations – in no particular order – are as follows:

a) Files: Both the AppleScript and the Find Command do a relative good job of identifying the files. AppleScript failed to identify 18 files which appeared in Finder. Find Command identified every file that appeared in Finder but also identified 216 extra files [i.e. files such a package contents, icon files, temporary files, etc.].

b) Folders: AppleScript failed to identify 210 folders/sub-folders which appeared in Finder. Find Command identified every folder/sub-folder that appeared in Finder but also identified 65 extra folders/sub-folders [i.e. folders such a package contents, etc.].

c) Conclusion: As the objective is to identify files whose pathnames exceed a prescribed length both AppleScript (identified 99.94% of the files) and Find Command (identified 100% of the files) are fairly reliable.

I will however be completing the script using the Find Command code as I would rather identify a few too many files over identifying a few too few files.

  1. With that, I will be completing the script over the weekend and sharing the final script so that anyone interested in it can tweak / use it or do whatever you want with it.

Thanks again to everyone who helped!

Objective-C, and therefore ASObjC, does not generally throw errors unless there’s something drastically wrong. So what happens when you try to create a folder is that the method returns true or false, depending on whether it succeeded. But because the folders were just making up the character count, and I knew they were going to be just short of the limit, I didn’t bother checking the result, to keep the script simpler. But once you started adding extra loops or characters to the folder name, the call to make the folder failed, but the script didn’t check so it didn’t strike a problem until the attempt to write the file to a non-existant folder.

If it weren’t a one-off, you would use something like:

set theResult to (theNSFileManager's createDirectoryAtPath:folderPath withIntermediateDirectories:true attributes:(missing value) |error|:(missing value))
if theResult as boolean is false then
  ...

Thanks Shane

I learnt something so it will be a good day.

Yvan KOENIG (VALLAURIS, France) samedi 13 décembre 2014 11:57:29

After finding a few hours to code / script I am ALMOST done…the resulting script [which I invite everyone to try produces – at least in my mind – a very good looking and useful spreadsheet] is as follows:


-- Provide the user with a dialog box that outlines the next two steps
display dialog "This script creates an Excel file that lists the file pathname's length and the file pathname of every file whose pathname is greater than a user specified maxCount in a user specified folder (which can be a drive).
 
The next step two steps, in order, are i) specifying the maxCount (for which a dialog box exists) and ii) specifying the  folder (for which a Finder Choose a Folder window exists)." buttons {"Okay"} default button 1 with icon note


tell application "Finder"
	
	-- Define the list of files whose pathnames exceed maxCount characters
	set fileList to {}
	
	
	-- Define / set maxCount characters
	display dialog "What is the maxCount of characters to test each filename's lenght against?

When entering a value make sure to adjust the value for the volume location / type [i.e. a Window's volume will have pathnames that start with \"C:\" in place of \"Volumes\" meaning that a value of 256 should be entered when wanting to test for a pathname length of 250 (i.e. 250 - 2 + 8)]." default answer "225" buttons {"Cancel", "Return"} default button 2 with icon note
	set maxCount to text returned of result
	
	
	-- Pick the disk / directory / folder (and sub-folders) whose files' pathnames will be compared / tested against maxCount	
	set FolderTarget to POSIX path of (choose folder with prompt "Choose the disk / directory / folder whose file lengths' will be compared against maxCount" default location (path to home folder))
	set FolderTarget to characters 1 through -2 of FolderTarget as text -- remove the second "/" between the folder chosen and any nested folders
	-- log "folderTarget"
	-- log folderTarget
	
	
	-- Set fileList to those filenames whose lengths are greater than maxCount
	script o
		property filePaths : ""
		property folderPaths : ""
	end script
	
	set o's filePaths to paragraphs of (do shell script "/usr/bin/find " & quoted form of FolderTarget & " -type f ! -type l ! -name '.*'")
	set o's folderPaths to paragraphs of (do shell script "/usr/bin/find " & quoted form of FolderTarget & " -type d")
	
	display dialog "Are the file pathname lengths being tested in HFS or POSIX file format?" buttons {"HFS", "POSIX"} default button 2 with icon note
	set fileFormat to button returned of result
	
	if fileFormat = "POSIX" then
		repeat with aPath in o's filePaths
			if (length of aPath) > maxCount then set end of fileList to contents of aPath -- as alias
		end repeat
		
	else
		
		repeat with aPath in o's filePaths
			set HFSPath to POSIX file aPath as text
			if (length of HFSPath) > maxCount then set end of fileList to HFSPath -- as alias
		end repeat
	end if
	
	
	-- Set fileList to include the count/index, the file pathname's length and the file's pathname
	repeat with i from 1 to count of fileList
		set item i of fileList to {count of item i of fileList, item i of fileList}
	end repeat
	
	
	-- Sort fileList based on the files' pathname lengths from highest to lowest to highest
	set callSortLocation to "Macintosh HD:Users:JoelC:Documents:Apple:Scripts:Utilities:20141125_script to sort a list of items_specific_complete.scpt" as alias -- Set callSort to load a compiled sorting script
	set callSort to (load script callSortLocation)
	tell callSort -- Tell callSort to sort fileList
		set fileList to simple_sort(fileList)
	end tell
	
	
	log "Total files are " & (count of o's filePaths)
	log "Total folders are " & (count of o's folderPaths)
	log "Total files and folders to compare to finder are " & ((count of o's filePaths) + (count of o's folderPaths) + 1) -- The 1 is for the parent folder
	log "The fileList follows"
	-- return fileList
	
end tell


tell application "Microsoft Excel"
	
	open
	
	
	-- Get current date in YYYYMMDD format	
	set currentDate to current date
	set currentDateYear to year of currentDate
	set currentDateMonth to month of currentDate as integer
	if ((day of currentDate < 10) is true) then
		set currentDateDay to "0" & day of currentDate
	else
		set currentDateDay to day of currentDate
	end if
	set currentDateYYYYMMDD to currentDateYear & currentDateMonth & currentDateDay as string
	
	
	-- Make and name a new workbook
	make new workbook
	set theBook to the active workbook
	set theSheet to the active sheet of the theBook
	-- set theBookName to the name of theBook
	-- set theSheetName to name of theSheet
	
	
	-- Move the workbook to the centre and forefront of the screen
	tell application "Moom"
		open
		arrange windows according to snapshot named "Align Microsoft Excel"
	end tell
	
	
	-- Set the magniifcation / zoom percentage
	set zoom of theSheet to 75
	
	
	-- Set the column widths in the new workbook for readability
	set column width of the first column of theSheet to 3
	set column width of the second column of theSheet to 5
	set column width of the third column of theSheet to 7
	set column width of the fourth column of theSheet to 200
	set column width of the fifth column of theSheet to 3
	
	
	-- Set and format the column heading and titles
	set myRangeCells to range ("B2:D2") of theSheet
	set weight of (get border of myRangeCells which border edge top) to border weight thick
	set borderWeightLog to get weight of (get border of myRangeCells which border edge top)
	
	set insertedTextTop to "Length and Pathname of Files Whose Pathnames Exceed " & maxCount & " Characters" as string
	set insertedTextBottom to "Selected Folder:  " & FolderTarget as string
	set myRangeTop to range ("B3:B3") of theSheet
	set myRangeBottom to range ("B4:B4") of theSheet
	set value of myRangeTop to insertedTextTop
	set value of myRangeBottom to insertedTextBottom
	
	set myRangeCells to range ("B7:D7") of theSheet
	set weight of (get border of myRangeCells which border edge top) to border weight thin
	set borderWeightLog to get weight of (get border of myRangeCells which border edge top)
	
	set myRangeCells to range ("B3:B3")
	set font size of font object of myRangeCells to 16
	set font style of font object of myRangeCells to "Bold"
	set fontStyleLog to (get font style of font object of myRangeCells)
	
	set myRangeCells to range ("B4:B4")
	set font style of font object of myRangeCells to "Bold"
	-- set fontStyleLog to (get font style of font object of myRangeCells)
	-- log fontStyleLog
	
	set insertedTextTop to "Path"
	set InsertedTextBottom1 to "Count"
	set InsertedtextBottom2 to "Length"
	set InsertedTextBottom3 to "Pathname"
	set myRangeTop to range ("C8:C8") of theSheet
	set myRangeBottom1 to range ("B9:B9") of theSheet
	set myRangeBottom2 to range ("C9:C9") of theSheet
	set myRangeBottom3 to range ("D9:D9") of theSheet
	set value of myRangeTop to insertedTextTop
	set value of myRangeBottom1 to InsertedTextBottom1
	set value of myRangeBottom2 to InsertedtextBottom2
	set value of myRangeBottom3 to InsertedTextBottom3
	
	set myRangeCells to range ("B8:D9") of theSheet
	set horizontal alignment of myRangeCells to horizontal align center
	
	set myRangeCells to range ("B11:C100000") of theSheet
	set horizontal alignment of myRangeCells to horizontal align center
	
	set myRangeCells to range ("B8:D9")
	-- set font size of font object of myRangeCells to 16
	set font style of font object of myRangeCells to "Bold"
	
	set myRangeCells to range ("B9:D9") of theSheet
	set weight of (get border of myRangeCells which border edge bottom) to border weight thin
	set borderWeightLog to get weight of (get border of myRangeCells which border edge bottom)
	
	
	-- Import fileList
	repeat with i from 1 to count of fileList
		set value of cell ("B" & (10 + i) as string) to i
		set value of cell ("C" & (10 + i) as string) to item 1 of item i of fileList
		set value of cell ("D" & (10 + i) as string) to item 2 of item i of fileList
	end repeat
	
	
	-- Set the name of the spreadsheet to be saved
	set userName to do shell script "whoami"
	set fileNameSaved to "Macintosh HD:Users:" & userName & ":Desktop:" & currentDateYYYYMMDD & "_files over " & maxCount & " charcters.xls"
	
	
	-- Save the workbook / spreadsheet
	tell theBook
		save workbook as theBook filename fileNameSaved overwrite yes
	end tell
	
	
	-- Test, and depending on the test result, close the spreadsheet
	display dialog "Do you want to close the Excel spreadsheet which lists the files whose pathnames are over " & maxCount & " characters?" buttons {"Yes", "No"} default button 2 giving up after 5
	set spreadsheetClose to button returned of result
	if ((spreadsheetClose = "Yes") is true) then quit
	
end tell

I wrote almost done above because I am running into two problems that I cannot solve:

  1. The code to set the magnification / zoom of the spreadsheet is commented out because it is not working…I cannot figure out why this is not working given this is – at least to me – the syntax suggested by the Excel dictionary and posted elsewhere on the net…help with this would be greatly appreciated.

  2. The code which converts the POSIX file format to the HFS file format is not working…help with this would be greatly appreciated.

Once again I want to thank everybody for taking the time to help an teach me.

Joel

A brief update on the above items using the same numbering.

  1. This problem is solved…I changed the syntax to read “set zoom of the active window to 75” which worked though in looking at Excel’s dictionary I cannot figure out why I needed to change “theSheet” to “active window”.

  2. This problem is still open…I do think that I have a solution but I need t code it…am looking for something easy and elegant rather my brute force approach which is to i) replace “/User” with “Macintosh HD” and ii) replace every “/” with “:”…anything out there?

Thx,

Joel

In the event that anyone is following this thread I have now solved both of the previously listed problems…the solution to the first problem is noted in the immediately preceding post…the solution to the second problem was fairly simple in that I had to coerce the POSIX pathname into a string before converting back to HFS format.

The final script – inclusive of a good amount of Excel code to produce a nicely formatted spreadsheet – is as follows:


-- Provide the user with a dialog box that outlines the next two steps
display dialog "This script creates an Excel file that lists the file pathname's length and the file pathname of every file whose pathname is greater than a user specified maxCount in a user specified folder (which can be a drive).
 
The next step two steps, in order, are i) specifying the maxCount (for which a dialog box exists) and ii) specifying the  folder (for which a Finder Choose a Folder window exists)." buttons {"Okay"} default button 1 with icon note


tell application "Finder"
	
	-- Define the list of files whose pathnames exceed maxCount characters
	set fileList to {}
	
	
	-- Define / set maxCount characters
	display dialog "What is the maxCount of characters to test each filename's lenght against?

When entering a value make sure to adjust the value for the file formath [i.e. HFS vs POSIX] and the volume location / type [i.e. a Window's volume will have pathnames that start with \"C:\" in place of \"\\Volumes\" meaning that a value of 256 should be entered when wanting to test for a pathname length of 250 (i.e. 250 - 2 + 8)]." default answer "225" buttons {"Cancel", "Return"} default button 2 with icon note
	set maxCount to text returned of result
	
	
	-- Pick the disk / directory / folder (and sub-folders) whose files' pathnames will be compared / tested against maxCount	
	set FolderTarget to POSIX path of (choose folder with prompt "Choose the disk / directory / folder whose file lengths' will be compared against maxCount" default location (path to home folder))
	set FolderTarget to characters 1 through -2 of FolderTarget as text -- remove the second "/" between the folder chosen and any nested folders
		
	
	-- Set fileList to those filenames whose lengths are greater than maxCount
	script o
		property filePaths : ""
		property folderPaths : ""
	end script
	
	set o's filePaths to paragraphs of (do shell script "/usr/bin/find " & quoted form of FolderTarget & " -type f ! -type l ! -name '.*'")
	set o's folderPaths to paragraphs of (do shell script "/usr/bin/find " & quoted form of FolderTarget & " -type d")
	
	display dialog "Are the file pathname lengths being tested in HFS or POSIX file format?" buttons {"HFS", "POSIX"} default button 2 with icon note
	set fileFormat to button returned of result
	
	if fileFormat = "POSIX" then
		repeat with aPath in o's filePaths
			if (length of aPath) > maxCount then set end of fileList to contents of aPath -- as alias
		end repeat
		
	else
		
		repeat with aPath in o's filePaths
			set HFSPath to POSIX file (aPath as string) as string
			if (length of HFSPath) > maxCount then set end of fileList to HFSPath -- as alias
		end repeat
	end if
	
	
	-- Set fileList to include the count/index, the file pathname's length and the file's pathname
	repeat with i from 1 to count of fileList
		set item i of fileList to {count of item i of fileList, item i of fileList}
	end repeat
	
	
	-- Sort fileList based on the files' pathname lengths from highest to lowest to highest
	set callSortLocation to "Macintosh HD:Users:JoelC:Documents:Apple:Scripts:Utilities:20141125_script to sort a list of items_specific_complete.scpt" as alias -- Set callSort to load a compiled sorting script
	set callSort to (load script callSortLocation)
	tell callSort -- Tell callSort to sort fileList
		set fileList to simple_sort(fileList)
	end tell
	
	
	log "Total files are " & (count of o's filePaths)
	log "Total folders are " & (count of o's folderPaths)
	log "Total files and folders to compare to finder are " & ((count of o's filePaths) + (count of o's folderPaths) + 1) -- The 1 is for the parent folder
	log "The fileList follows"
	-- return fileList
	
end tell


tell application "Microsoft Excel"
	
	open
	
	
	-- Get current date in YYYYMMDD format	
	set currentDate to current date
	set currentDateYear to year of currentDate
	set currentDateMonth to month of currentDate as integer
	if ((day of currentDate < 10) is true) then
		set currentDateDay to "0" & day of currentDate
	else
		set currentDateDay to day of currentDate
	end if
	set currentDateYYYYMMDD to currentDateYear & currentDateMonth & currentDateDay as string
	
	
	-- Make and name a new workbook
	make new workbook
	set theBook to the active workbook
	set theSheet to the active sheet of the theBook
	-- set theBookName to the name of theBook
	-- set theSheetName to name of theSheet
	
	
	-- Move the workbook to the centre and forefront of the screen
	tell application "Moom"
		open
		arrange windows according to snapshot named "Align Microsoft Excel"
	end tell
	
	
	-- Set the magniifcation / zoom percentage
	set zoom of the active window to 75
	
	
	-- Set the column widths in the new workbook for readability
	set column width of the first column of theSheet to 3
	set column width of the second column of theSheet to 5
	set column width of the third column of theSheet to 7
	set column width of the fourth column of theSheet to 250
	set column width of the fifth column of theSheet to 3
	
	
	-- Set and format the column heading and titles
	set myRangeCells to range ("B2:D2") of theSheet
	set weight of (get border of myRangeCells which border edge top) to border weight thick
	set borderWeightLog to get weight of (get border of myRangeCells which border edge top)
	
	set insertedTextTop to "Length and Pathname of Files Whose Pathnames Exceed " & maxCount & " Characters" as string
	set insertedTextBottom to "Selected Folder:  " & FolderTarget as string
	set myRangeTop to range ("B3:B3") of theSheet
	set myRangeBottom to range ("B4:B4") of theSheet
	set value of myRangeTop to insertedTextTop
	set value of myRangeBottom to insertedTextBottom
	
	set myRangeCells to range ("B7:D7") of theSheet
	set weight of (get border of myRangeCells which border edge top) to border weight thin
	set borderWeightLog to get weight of (get border of myRangeCells which border edge top)
	
	set myRangeCells to range ("B3:B3")
	set font size of font object of myRangeCells to 16
	set font style of font object of myRangeCells to "Bold"
	set fontStyleLog to (get font style of font object of myRangeCells)
	
	set myRangeCells to range ("B4:B4")
	set font style of font object of myRangeCells to "Bold"
	-- set fontStyleLog to (get font style of font object of myRangeCells)
	-- log fontStyleLog
	
	set insertedTextTop to "Path"
	set InsertedTextBottom1 to "Count"
	set InsertedtextBottom2 to "Length"
	set InsertedTextBottom3 to "Pathname"
	set myRangeTop to range ("C8:C8") of theSheet
	set myRangeBottom1 to range ("B9:B9") of theSheet
	set myRangeBottom2 to range ("C9:C9") of theSheet
	set myRangeBottom3 to range ("D9:D9") of theSheet
	set value of myRangeTop to insertedTextTop
	set value of myRangeBottom1 to InsertedTextBottom1
	set value of myRangeBottom2 to InsertedtextBottom2
	set value of myRangeBottom3 to InsertedTextBottom3
	
	set myRangeCells to range ("B8:D9") of theSheet
	set horizontal alignment of myRangeCells to horizontal align center
	
	set myRangeCells to range ("B11:C100000") of theSheet
	set horizontal alignment of myRangeCells to horizontal align center
	
	set myRangeCells to range ("B8:D9")
	-- set font size of font object of myRangeCells to 16
	set font style of font object of myRangeCells to "Bold"
	
	set myRangeCells to range ("B9:D9") of theSheet
	set weight of (get border of myRangeCells which border edge bottom) to border weight thin
	set borderWeightLog to get weight of (get border of myRangeCells which border edge bottom)
	
	
	-- Import fileList
	repeat with i from 1 to count of fileList
		set value of cell ("B" & (10 + i) as string) to i
		set value of cell ("C" & (10 + i) as string) to item 1 of item i of fileList
		set value of cell ("D" & (10 + i) as string) to item 2 of item i of fileList
	end repeat
	
	
	-- Set the name of the spreadsheet to be saved
	set userName to do shell script "whoami"
	set fileNameSaved to "Macintosh HD:Users:" & userName & ":Desktop:" & currentDateYYYYMMDD & "_files over " & maxCount & " charcters.xls"
	
	
	-- Save the workbook / spreadsheet
	tell theBook
		save workbook as theBook filename fileNameSaved overwrite yes
	end tell
	
	
	-- Test, and depending on the test result, close the spreadsheet
	display dialog "Do you want to close the Excel spreadsheet which lists the files whose pathnames are over " & maxCount & " characters?" buttons {"Yes", "No"} default button 2 giving up after 5
	set spreadsheetClose to button returned of result
	if ((spreadsheetClose = "Yes") is true) then quit
	
end tell

To anyone who asks why create the script given the large pathname lengths allowed in OS X / Unix the answer is that unfortunately I work in a Windows world which has a pathname length of 255 characters which is rather limiting – at least to me – meaning backups, file transfers, etc. often fail because the pathnames are too long.

To avoid this problem I run this script against my Windows volume which is connected as a network drive to identify those pathnames that I have to shorten before running a backup, file transfer, etc.

Why write this script in Applescript…because I prefer an Apple world over a Windows world!

***

With much thanks to all those who helped get this script up and running!

Joel