Firstly, I should point out that I am very new to this and hoped I might get some help here.
I’m trying to generate a text file that records the name and date modified properties of all folders on an SMB file server.
I managed this:
tell application “Finder”
activate
set _folder to POSIX path of ((folder of the front window) as alias)
set _files to (get selection)
set _file to item 1 of _files
set _name to (name of _file)
set _date to (creation date of _file)
set {year:y, month:m, day:d, hours:h, minutes:m} to _date
set the clipboard to (_name & " " & _date)
end tell
However that only records them one by one and I’d like my script to copy this information in one go so I can paste into txt edit, Is this possible?
Sorry, I see what you mean… Yes, the script gets the name and creation/modified date of the first item (file or folder)
but not folders contained within.
set theFolder to quoted form of posix path of (choose folder)
do shell script "find " & theFolder & " -maxdepth 1 -type d -exec stat -f '%Sm%t%Sc%t%N' -t '%Y-%m-%d %H:%m:%S' {} + > $HOME/Desktop/Report.txt"
A file on your desktop name Report.txt is created after it is finished.
Wow thank you, not sure how you mean by recursive?
I have a work folder that contains 100s of job folders with a job number on each.
I just want to record the job number and date modified of the folder, but not what is contained in the folders.
I ran that script which works really well but records the folders contents.
Here is an alternate scheme with no limit for the deep of folders hierarchy.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on run
my germaine()
end run
on germaine()
set sourceFolder to POSIX path of (choose folder)
set theFoldersInfos to my listFoldersIn:sourceFolder
set theData to my recolle(theFoldersInfos, linefeed)
set targetFile to POSIX path of ((path to desktop as text) & "myFiles_seliFym.txt")
my writeToReport(targetFile, theData, «class utf8», false)
end germaine
on listFoldersIn:sourceFolder
set dirKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set fileManager to current application's NSFileManager's defaultManager()
set aURL to current application's |NSURL|'s fileURLWithPath:sourceFolder
set theOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
set theEnumerator to fileManager's enumeratorAtURL:aURL includingPropertiesForKeys:{} options:theOptions errorHandler:(missing value)
set theList to {"modification dates" & tab & "folders paths"}
repeat with aURL in theEnumerator's allObjects()
set isFile to true
-- is it a directory?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:dirKey |error|:(reference))
if theValue as boolean then
-- is it a package?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:packageKey |error|:(reference))
if not theValue as boolean then
set isFile to false
end if
end if
if not isFile then
set {theResult, theModDate} to (aURL's getResourceValue:(reference) forKey:(current application's NSURLContentModificationDateKey) |error|:(missing value))
set aDescriptor to ((theModDate's |description|()) as text) & tab & aURL's |path|() as text
set end of theList to aDescriptor
end if
end repeat
return theList
end listFoldersIn:
#=====#=====#=====#=====#=====#=====
on recolle(l, d)
local oTIDs, t
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end recolle
#=====#=====#=====#=====#=====#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeToReport(targetFile, theData, dataType, apendData)
-- theData is the data you want in the file.
-- dataType is the data type of theData and it can be text, list, record etc.
-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
try
set targetFile to targetFile as «class furl»
set openFile to open for access targetFile with write permission
if not apendData then set eof of openFile to 0
write theData to openFile starting at eof as dataType
close access openFile
return true
on error
try
close access targetFile
end try
return false
end try
end writeToReport
#=====#=====#=====#=====#=====#=====
Yvan KOENIG running Sierra 10.12.5 in French (VALLAURIS, France) lundi 26 juin 2017 21:09:34
For the record: My command above can be adjusted by the -maxdepth value to any level you want or remove the parameter entirely if you don’t want a limit like Yvan’s script.
The disadvantage of DJ’s approach is that it will also treat any packages, such as applications, as directories. In the immediate use case that might not matter, but in other cases it can matter a lot.
If you only want to go one level deep, the listFoldersIn: handler in Yvan’s script can be made a bit more efficient like this:
on listFoldersIn:sourceFolder
set dirKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set fileManager to current application's NSFileManager's defaultManager()
set aURL to current application's |NSURL|'s fileURLWithPath:sourceFolder
set theURLs to fileManager's contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{dirKey, packageKey} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
set theList to {"modification dates" & tab & "folders paths"}
repeat with aURL in theURLs
set isFile to true
-- is it a directory?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:dirKey |error|:(reference))
if theValue as boolean then
-- is it a package?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:packageKey |error|:(reference))
if not theValue as boolean then
set isFile to false
end if
end if
if not isFile then
set {theResult, theModDate} to (aURL's getResourceValue:(reference) forKey:(current application's NSURLContentModificationDateKey) |error|:(missing value))
set aDescriptor to ((theModDate's |description|()) as text) & tab & aURL's |path|() as text
set end of theList to aDescriptor
end if
end repeat
return theList
end listFoldersIn:
And if you want the ability to specify how deep to look, you con do something like this:
on listFoldersIn:sourceFolder toLevel:levelNumber
set dirKey to current application's NSURLIsDirectoryKey
set packageKey to current application's NSURLIsPackageKey
set fileManager to current application's NSFileManager's defaultManager()
set aURL to current application's |NSURL|'s fileURLWithPath:sourceFolder
set theOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
set theEnumerator to fileManager's enumeratorAtURL:aURL includingPropertiesForKeys:{dirKey, packageKey} options:theOptions errorHandler:(missing value)
set theList to {"modification dates" & tab & "folders paths"}
repeat
set aURL to theEnumerator's nextObject()
if aURL is missing value then exit repeat
set isFile to true
-- is it a directory?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:dirKey |error|:(reference))
if theValue as boolean then
-- is it a package?
set {theResult, theValue, theError} to (aURL's getResourceValue:(reference) forKey:packageKey |error|:(reference))
if not theValue as boolean then
set isFile to false
end if
end if
if not isFile then
set {theResult, theModDate} to (aURL's getResourceValue:(reference) forKey:(current application's NSURLContentModificationDateKey) |error|:(missing value))
set aDescriptor to ((theModDate's |description|()) as text) & tab & aURL's |path|() as text
set end of theList to aDescriptor
if theEnumerator's level() = levelNumber then theEnumerator's skipDescendants()
end if
end repeat
return theList
end listFoldersIn:toLevel:
True, if that would be important you could use mdfind and xargs to do the same. I assumed it would not be important because of the SMB volume, so I went go for the much faster find command in this case.