Hi all. I’m having trouble quoting this command line into a “do shell script” form to simply list every visible file on an external disk, writing one path per line into a text file, but suppressing any line that begins with a period. Can someone help? Thanks!
This is my latest try, which doesn’t work:
find /Volumes/External HD -not -path '*/\.*' -type f \( ! -iname ".*" \) > ~/Desktop/allfiles-External HD.txt
Thanks. Yes, the command works in Terminal, but in an AppleScript it requires a "do shell script " & the CLI command itself, which requires some kind of escaping of characters such as those found in the “‘/.’ -type f ( ! -iname “.*” )” part of the command string.
Do you know how I can properly escape this whole command:
`
find /Volumes/External HD -not -path ‘/.’ -type f ( ! -iname “.*” ) > ~/Desktop/allfiles-External HD.txt.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set cc to "find " & quoted form of "/Volumes/Crucial SSD" & " -not -path '*/\\.*' -type f \\( ! -iname \".*\" \\) > " & "~/Desktop/allfiles-External\\ HD.txt 2>&1"
do shell script cc
For some reason you cant use 'quoted form of ’ on file output portion of the string. you have to doubele escape the spaces. (i.e. “~/Desktop/allfiles-External\\ HD.txt”)
Not sure but I think this is because of the tilde. The tilde can’t be expanded if we provide a path in straight quotes (which is what quoted form of does) as every string in straight quotes is seen as a literal without any change applied.
BTW, you can also use my program “Find Any File” (shareware, i.e. you can try it out before buy). You can then use the rule “Path doesn’t contain /.” to find all files that do not start with a “.”.
You can wait for the results window to appear, then Save to a file, which will contain all the found paths. Or you add a rule “Pass results to …” (hold down option key to see that rule) where you can either send it directly to a file or to an application, e.g. a script of yours.
Note that that FAF is not scriptable in case you rely on that (I wanted to add AppleScript support for years, but it’s a lot of work).
Hi Tempel. I actually own Find Any File because it’s indispensable for finding anything anywhere, but have never explored this functionality. I just tried it on my startup disk. It worked but I couldn’t get it to output one full path per line. Thanks though!
The OP wants to use the find command, and Robert has supplied that. FWIW, the following is an ASObjC solution. It returns regular files and skips hidden files, packages, and package contents, although it’s easily modified to include these.
use framework "Foundation"
use scripting additions
set theVolume to "/Volumes/Backup 1/" -- set to desired value
set textFile to POSIX path of (path to desktop) & "allfiles-External HD.txt"
writeFiles(theVolume, textFile)
on writeFiles(theVolume, textFile)
set theVolume to current application's |NSURL|'s fileURLWithPath:theVolume
set fileManager to current application's NSFileManager's defaultManager()
set fileKey to current application's NSURLIsRegularFileKey
set theFiles to (fileManager's enumeratorAtURL:theVolume includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects()'s mutableCopy()
repeat with i from theFiles's |count|() to 1 by -1
set {theResult, aRegularFile} to ((theFiles's objectAtIndex:(i - 1))'s getResourceValue:(reference) forKey:fileKey |error|:(missing value))
if aRegularFile as boolean is false then (theFiles's removeObjectAtIndex:(i - 1))
end repeat
set theString to (theFiles's valueForKey:"path")'s componentsJoinedByString:linefeed
theString's writeToFile:textFile atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
end writeFiles
Hi Tempel: Basically, the find and the Pass Results worked. However, I couldn’t manage to filter things like folder lines and package contents. An Ends With could be useful in addition to the Begins With, but I don’t think it can currently give me the one normal visible file per line output I was seeking. Thanks!
Peavine, your script outputs exactly what I was looking for: one normal visible full file path per line. It’s fast too, taking just a few seconds for around 600,000 files. I’m going to use it to populate Filemaker databases.
Note: I must have googled and tried dozens of scripts, but they all failed or I couldn’t construct the output criteria correctly. I eventually had almost given up and I used my Livecode license to make a little stack, which worked fine. But I think it’s essential to have this script in my repertoire, even if I don’t understand ASObjC! So thanks thanks thanks!
Peavine, I’ve tried your script and is does in fact work perfectly, with one small issue. The output text file does not list in alphabetical order. Any chance that feature can be added?
I see you got your task resolved with Peavine’s help, but I’d still like to make sure that FAF can handle special searches like yours, too.
Would you be willing to help me improve FAF in this regard (I’d like to understand better what didn’t work and make sure you didn’t miss an option that would’ve solved it)? Then please contact me here with a PM.
Thanks!
There’s a “Name ends with” rule you can add. Or the newer “Extension is” rule. And there’s also “Kind is not Directory”, or the hidden (“expert”, see manual) rule “Is Folder No”.
Then there’s the rule “Package Items are not shown”, though that may indeed not have the desired effect when saving the results to a file (meaning that they’ll end up in the file regardless because this option is only filtering them out in the results window, even though they’re still part of the “found” set - that’s something I could fix, indeed).
Give these rules a try if you have the time and let me know if that gives you better results.
Homer712. I’ve modified my script to sort the output text in alphabetical order. I’ve also changed some variable names, since this and my previous script work with both volumes and folders. The sort selector used works in the same fashion as the Finder (it is case insensitive and numbers are sorted numerically instead of lexically). This is easily changed.
use framework "Foundation"
use scripting additions
set theFolder to "/Users/Robert/Documents/" -- set to desired value
set textFile to POSIX path of (path to desktop) & "All Files.txt"
writeFiles(theFolder, textFile)
on writeFiles(theFolder, textFile)
set fileManager to current application's NSFileManager's defaultManager()
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
set fileKey to current application's NSURLIsRegularFileKey
set theFiles to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects()'s mutableCopy()
repeat with i from theFiles's |count|() to 1 by -1
set {theResult, aRegularFile} to ((theFiles's objectAtIndex:(i - 1))'s getResourceValue:(reference) forKey:fileKey |error|:(missing value))
if aRegularFile as boolean is false then (theFiles's removeObjectAtIndex:(i - 1))
end repeat
set sortedFiles to (theFiles's valueForKey:"path")'s sortedArrayUsingSelector:"localizedStandardCompare:"
set theString to sortedFiles's componentsJoinedByString:linefeed
theString's writeToFile:textFile atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
end writeFiles
Not only does the script work perfectly, it is incredibly fast. The file seems to pop up on the desktop just as soon as the run arrow is clicked. Thank you, I can see many uses for this kind of script. Now, I’m not asking (because I’d like to see if I can figure it out myself), but I’m going to try to have the output be a PDF. I asked you once in another thread and I’ll look at that one where you went from TXT to PDF.
After three cups of coffee I have a working txt to pdf conversion. Not very polished, but it works.
use framework "Foundation"
use scripting additions
set theFolder to "/Users/homer/Documents/" -- set to desired value
set textFile to POSIX path of (path to desktop) & "All Files.txt"
writeFiles(theFolder, textFile)
on writeFiles(theFolder, textFile)
set fileManager to current application's NSFileManager's defaultManager()
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
set fileKey to current application's NSURLIsRegularFileKey
set theFiles to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects()'s mutableCopy()
repeat with i from theFiles's |count|() to 1 by -1
set {theResult, aRegularFile} to ((theFiles's objectAtIndex:(i - 1))'s getResourceValue:(reference) forKey:fileKey |error|:(missing value))
if aRegularFile as boolean is false then (theFiles's removeObjectAtIndex:(i - 1))
end repeat
set sortedFiles to (theFiles's valueForKey:"path")'s sortedArrayUsingSelector:"localizedStandardCompare:"
set theString to sortedFiles's componentsJoinedByString:linefeed
theString's writeToFile:textFile atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
end writeFiles
tell application "TextEdit"
activate
open "/Users/homer/Desktop/All Files.txt/"
tell (windows whose id is not (get id of front window) and visible is true)
set miniaturized to true
end tell
set bounds of front window to {279, 111, 1180, 719}
tell application "System Events"
click menu item "Export as PDF…" of menu 1 of menu bar item "File" of menu bar 1 of application process "TextEdit"
end tell
end tell