Find same named folders and copy folder to all of them.

Hi I have to create a script that searches for multiple folders all with the same name,
on a volume and then copy another folder and its contents to the searched folders.

‘04_Design’ (folder name being searched for)
‘Assets’ (folder to be copied) to go into every 04_Design folder found.

Im struggling… i have found lots of folder finding solutions but none for multiple instances.
so none of my scripts work.

So any help would be great…

Thanks Rob

This should work, so long as the volume is indexed in spotlight. I used mdfind because it’s much faster than any AppleScript equivalent.

set theFolders to paragraphs of (do shell script "/usr/bin/mdfind -onlyin " & quoted form of "/Volumes/volume name" & " 'kMDItemFSName = \"04_Design\" && kMDItemContentType = \"public.folder\"'")

repeat with thisFolder in theFolders
	-- need this weird coercion because the Finder only likes HFS (colon-delimited) paths or aliases
	set folderPath to (POSIX file thisFolder) as text
	set assetsPath to (POSIX file "/path/to/folder/Assets") as text
	tell application "Finder"
		duplicate folder assetsPath to folder folderPath
	end tell
end repeat

Test it on something disposable first, or make a backup of the volume; there’s no ‘undo’ option here.

I think you’ll find this is quicker (requires my Metadata Lib):

use AppleScript version "2.5" -- macOS 10.11 or later
use scripting additions
use script "Metadata Lib" version "2.0.2"

set thePath to POSIX path of (choose folder with prompt "choose the volume")
set theFolders to perform search in folders {thePath} predicate string "kMDItemFSName = %@ AND kMDItemContentType = %@" search arguments {"04_Design", "public.folder"}
-- now do duplicating

But the poster says “on a volume”, and that could well mean a volume that doesn’t support Spotlight indexing, in which case neither of our scripts are any use. In which case he could use:

use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions

-- classes, constants, and enums used
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to 4
property NSDirectoryEnumerationSkipsPackageDescendants : a reference to 2
property NSURLIsDirectoryKey : a reference to current application's NSURLIsDirectoryKey
property NSURLIsPackageKey : a reference to current application's NSURLIsPackageKey

set thePath to POSIX path of (choose folder with prompt "choose the volume")
set volURL to current application's NSURL's fileURLWithPath:thePath
set fileManager to current application's NSFileManager's |defaultManager|()
set theOptions to (NSDirectoryEnumerationSkipsPackageDescendants + NSDirectoryEnumerationSkipsHiddenFiles)
set theKeys to {NSURLIsDirectoryKey, NSURLIsPackageKey}
set theFolders to (fileManager's enumeratorAtURL:volURL includingPropertiesForKeys:theKeys options:theOptions errorHandler:(missing value))'s allObjects()
set thePred to current application's NSPredicate's predicateWithFormat_("lastPathComponent == %@", "04_Design")
set theFolders to theFolders's filteredArrayUsingPredicate:thePred
set folderList to current application's NSMutableArray's array()
repeat with aFolder in theFolders
	set {theResult, theValue} to (aFolder's getResourceValue:(reference) forKey:(NSURLIsDirectoryKey) |error|:(missing value))
	if theValue as boolean then
		-- is it a package?
		set {theResult, theValue} to (aFolder's getResourceValue:(reference) forKey:(NSURLIsPackageKey) |error|:(missing value))
		if not theValue as boolean then -- must be folder
			(folderList's addObject:aFolder)
		end if
	end if
end repeat
set thePaths to (folderList's valueForKey:"path") as list
-- now do the duplicating

I deleted this post and the Applescript it contained because it may not work properly with packages. Peavine.

Anything other than Spotlight-based searching is going to be slow on large volumes, though.

Using find is a little quicker than the code I posted above, depending on the volume. The problem is that find can’t distinguish between packages and directories, so it recursively searches inside packages. That not only means you risk getting results you don’t want, but if you have a lot of packages – an /Applications folder, say, – it will spend a lot of time search stuff you’re usually not interested in.

Shane. I didn’t know that the find utility searches in packages. That’s good to know (although unfortunate).

I have a number of volmes that contain data files only and that are very large. I ran some tests and my script ran quickly on these.

Anyways, the OP has a number of choices whatever his needs.

It’s a bit of a trap. Unix tools operate at the Unix level, which means they often don’t account for anything macOS builds on top of the Unix layer.

Find’s basic syntax is a shotgun approach, so it just finds everything. If you want specificity, then you have to tailor the search with the tool’s options. This should restrict searching files in packages and, optionally, named packages at the root level.

do shell script "find -E " & (path to desktop folder as text)'s POSIX path & " -name '*.*' -prune " #     ! -regex '.*(scptd|app|rtfd|download|fcarch).*' 

Marc. Thanks for the post. I’ve always associated packages with apps, but in fact they include much more. Perhaps that’s what Shane was referring to when he said “It’s a bit of a trap.”

That’s right. And trying to build a list of them is just writing code waiting to fail at some future point.

Thanks everyone for all your contributions and sorry i haven’t gotten back sooner…
Only just had time to look at this…

Shane your solution works great, you’re right its not indexed via spotlight.
I do get a list of the folders with 04_Design which is great…

I am however struggling to convert that so as to duplicate a folder to the path returned?

How would i best convert the path as list to something i can duplicate the folder to please?

Thanks Rob

You might as well copy as you find them. So:

use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions

-- classes, constants, and enums used
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to 4
property NSDirectoryEnumerationSkipsPackageDescendants : a reference to 2
property NSURLIsDirectoryKey : a reference to current application's NSURLIsDirectoryKey
property NSURLIsPackageKey : a reference to current application's NSURLIsPackageKey

set folderToCopy to POSIX path of (choose folder with prompt "choose the folder to copy")
set folderToCopyURL to current application's NSURL's fileURLWithPath:folderToCopy
set folderName to folderToCopyURL's lastPathComponent()
set thePath to POSIX path of (choose folder with prompt "choose the volume")
set volURL to current application's NSURL's fileURLWithPath:thePath
set fileManager to current application's NSFileManager's |defaultManager|()
set theOptions to (NSDirectoryEnumerationSkipsPackageDescendants + NSDirectoryEnumerationSkipsHiddenFiles)
set theKeys to {NSURLIsDirectoryKey, NSURLIsPackageKey}
set theFolders to (fileManager's enumeratorAtURL:volURL includingPropertiesForKeys:theKeys options:theOptions errorHandler:(missing value))'s allObjects()
set thePred to current application's NSPredicate's predicateWithFormat_("lastPathComponent == %@", "04_Design")
set theFolders to theFolders's filteredArrayUsingPredicate:thePred
set folderList to current application's NSMutableArray's array()
repeat with aFolder in theFolders
	set {theResult, theValue} to (aFolder's getResourceValue:(reference) forKey:(NSURLIsDirectoryKey) |error|:(missing value))
	if theValue as boolean then
		-- is it a package?
		set {theResult, theValue} to (aFolder's getResourceValue:(reference) forKey:(NSURLIsPackageKey) |error|:(missing value))
		if not theValue as boolean then -- must be folder
			--(folderList's addObject:aFolder)
			set destURL to (aFolder's URLByAppendingPathComponent:folderName)
			(fileManager's copyItemAtURL:folderToCopyURL toURL:destURL |error|:(missing value))
		end if
	end if
end repeat
--set thePaths to (folderList's valueForKey:"path") as list

Hi Shane…

Wow thanks for the quick reply and all the work too…
Its unfortunately having an error

on set destPath to (aFolder’s stringByAppendingPathComponent:folderName)

error “-[NSURL stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x6000025e17a0” number -10000

Any ideas?

Thanks Rob

Try the edited version.

Thanks Shane that’s super quick…

Unfortunately its another issue now…Its not understanding the lastPathComponent

set folderName to folderToCopy’s lastPathComponent()

Thanks Rob

Aaah! Should be “folderToCopyURL’s lastPathComponent()”

You my friend are a star and a far more competent applescripter than myself…!!
It works just as intended.

A very big thank you for helping me with this…

Much Appreciated…

Thanks Rob