Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Automator: Making folders with an incremental counter prefix

new to automator, and hit a wall. Within a static directory I'm trying to enter a folder name, make a folder with a 3 digit incremental counter (001, 002, etc.) then make 6 static folders based off of the folder name without the counter. What i've got so far is working well enough, but I have to manually add the counter to each folder. Is there a way to do this in Automator where it would read the working directory for the last folder created, take the first 3 digits and assign that as variable, increment it, then create a new folder? Looking at substring commands in bash, but I'm afraid I don't understand how to make it read the string and continually move forward.


I'm running the automator fresh each time, so I'd be unable to keep a running variable stored within the code.


What I have so far:

MacBook Pro with Touch Bar

Posted on Dec 22, 2020 4:23 PM

Reply
Question marked as Best reply

Posted on Jan 4, 2021 11:31 AM

> the part that I can't figure out is how to make the directory path dynamic


Ahh, welcome to the world of paths in AppleScript :)


For various historical/legacy/unknown(?) reasons, there are multiple ways of identifying directories in AppleScript. Not all of them work in all cases, so you need to know not only which directory you want, but also which application you'll be targeting when you use it.


For reference, the four common ways are:


alias - a 'universal' directory item - can point to any disk item (file, directory, etc.) and is persistent (e.g. if you create an alias to an item, and that item is subsequently moved or renamed, the alias object still references it correctly). Aligned with, but not related to Finder aliases.

path - a simple text object defining the path to a file in MacOS/HFS path (e.g. "Macintosh HD:Users:Username:Documents:some.jpg")

POSIX path - similar to path above, but using UNIX-style paths (e.g. "/Users/Username/Documents/some.jpg", or "~/Documents/some.jpg"

Finder references - somewhat verbose format of the path, e.g. File "some.jpg" of folder "Documents" of folder "Username" of folder "Users" of volume "Macintosh HD". Finder references actually have a lot of other metadata attached to them so they can be useful if you're manipulating files based on that.


You can also use the 'path to' command to dynamically find common folders, such as the user's home directory (path to home folder), Documents folder (path to documents folder) and more).


Finder references only work in the Finder, but the various methods can be coerced to each other, for example:


tell application "Finder"
  file "some.jpg" of (path to home folder) --> finder file object
  file "some.jpg" of (path to home folder) as text --> "Macintosh HD:Users:username:some.jpg"
  POSIX path of (file "some.jpg" of (path to home folder) as text) --> "/Users/username/some.jpg"
end tell

> For the sake of simplicity in the question the folder just lived in a generic desktop folder, but if I wanted to make it nested I can't figure out how to set it to the correct path


In my AppleScript example, I'm using Finder objects, so you can just prepend to get to where you want to go. Therefore, instead of:


	set base_folder to folder "Capture" of (path to desktop)


you could say:


set base_folder to folder "subfolder" of folder "anotherfolder" of folder "Capture" of (path to desktop)


You can also coerce back from a POSIX file to a Finder object if you have it in POSIX form, but given your example it's probably easier to say:


set base_folder to folder "Capture" of folder "sbx digital jobs" of (path to home folder)


Since the Finder inherently supports spaces in filenames, you don't need to get into escaping spaces and other characters.


hth

Similar questions

10 replies
Question marked as Best reply

Jan 4, 2021 11:31 AM in response to deej668

> the part that I can't figure out is how to make the directory path dynamic


Ahh, welcome to the world of paths in AppleScript :)


For various historical/legacy/unknown(?) reasons, there are multiple ways of identifying directories in AppleScript. Not all of them work in all cases, so you need to know not only which directory you want, but also which application you'll be targeting when you use it.


For reference, the four common ways are:


alias - a 'universal' directory item - can point to any disk item (file, directory, etc.) and is persistent (e.g. if you create an alias to an item, and that item is subsequently moved or renamed, the alias object still references it correctly). Aligned with, but not related to Finder aliases.

path - a simple text object defining the path to a file in MacOS/HFS path (e.g. "Macintosh HD:Users:Username:Documents:some.jpg")

POSIX path - similar to path above, but using UNIX-style paths (e.g. "/Users/Username/Documents/some.jpg", or "~/Documents/some.jpg"

Finder references - somewhat verbose format of the path, e.g. File "some.jpg" of folder "Documents" of folder "Username" of folder "Users" of volume "Macintosh HD". Finder references actually have a lot of other metadata attached to them so they can be useful if you're manipulating files based on that.


You can also use the 'path to' command to dynamically find common folders, such as the user's home directory (path to home folder), Documents folder (path to documents folder) and more).


Finder references only work in the Finder, but the various methods can be coerced to each other, for example:


tell application "Finder"
  file "some.jpg" of (path to home folder) --> finder file object
  file "some.jpg" of (path to home folder) as text --> "Macintosh HD:Users:username:some.jpg"
  POSIX path of (file "some.jpg" of (path to home folder) as text) --> "/Users/username/some.jpg"
end tell

> For the sake of simplicity in the question the folder just lived in a generic desktop folder, but if I wanted to make it nested I can't figure out how to set it to the correct path


In my AppleScript example, I'm using Finder objects, so you can just prepend to get to where you want to go. Therefore, instead of:


	set base_folder to folder "Capture" of (path to desktop)


you could say:


set base_folder to folder "subfolder" of folder "anotherfolder" of folder "Capture" of (path to desktop)


You can also coerce back from a POSIX file to a Finder object if you have it in POSIX form, but given your example it's probably easier to say:


set base_folder to folder "Capture" of folder "sbx digital jobs" of (path to home folder)


Since the Finder inherently supports spaces in filenames, you don't need to get into escaping spaces and other characters.


hth

Dec 22, 2020 5:15 PM in response to Camelot

Here’s the desired output.


I want to create a new named folder each time it’s run, running it as many times as needed. Would it make more sense to have it stay open instead of being a one time use/rerunning it as needed? Seems like that would eliminate me needing to hardcode the directory and make it dynamic for me to share with anyone else.

Dec 23, 2020 5:06 PM in response to Camelot

Here is the Zsh equivalent that produces the following when run using my own folder:



#!/bin/zsh

zmodload zsh/regex

function ask_for_foldername () {
    osascript <<-AS
    return text returned of (display dialog "Enter the new name:" default answer "name")
AS
}

# extract name1 from 001_name1
regex="^[0-9_]+(.*)$"

cd ~/Desktop/Metadata
folder="$(ask_for_foldername)"

mkdir -p "${folder}" && cd "${folder}"
# assign capture to subdirname if match or exit
[[ "${folder}" -regex-match $regex ]] && subdirname="$match" || exit 1

print $subdirname
# make the six subfolders based on subdirname string
for n in $(seq 1 6);
do
    mkdir -p "${subdirname}_${n}"
done
exit 1


This can be run from the Terminal as:


chmod +x ./f.zsh
./f.zsh


Dec 22, 2020 4:52 PM in response to deej668

Looping and variable handling are two of Automator's absolutely worst 'features'. It really doesn't handle either well.


Fortunately what you ask for is pretty easy to handle via AppleScript. You can embed it in your Automator workflow using the 'Run AppleScript' action.


The only sticky part is your statement:


> Automator where it would read the working directory for the last folder created


There is no inherent 'working directory' like there is in the shell. You need to somehow identify where the new folders should be created - this could be fixed (e.g. on your desktop, Documents folder, etc.), via prompting the user, by looking at the Finder's open windows, or anything else, but there does need to be something.


Given that your bash script doesn't do what you want, can you show an example of your desired outcome, then we can get a script to do it. As it stands it isn't clear where the 6 static folders are supposed to be... are they inside the new folder? Also how many times is this supposed to run? You say you want to increment the folder number but don't impose any limits.

Dec 23, 2020 9:56 AM in response to deej668

That helps, but still needs more.


For example, let's assume you have an empty 'Capture' folder as your starting point. Is that always the same? Or does that change?


I think what you're saying is that if the script was run right now, it would somehow look at the 'Capture' folder and:


1) see that the highest number used right now is 003

2) prompt the user for the new folder name (let's say that's "foo")

3) create a new folder by incrementing the counter from step 1 above, and appending the entered name

4) inside this new folder created at step 3, make 6 new folders with the name entered in step 2 with the numbers 1-6 appended.


Is that right?


If so, here's a pure AppleScript solution that you can either run standalone via Script Editor, or via an Automator 'run AppleScript' action


tell application "Finder"
	-- here's the starting point.
	-- can be changed to be dynamic or prompt the user if needed
	set base_folder to folder "Capture" of (path to desktop)
	
	-- ask the user for the new name
	set _name to text returned of (display dialog "Enter the new name:" default answer "name" buttons {"Cancel", "OK"} default button "OK")
	
	-- count how many folders already exist
	-- may need to adjust this logic if count isn't sufficient
	set top_folder_count to count (every folder of base_folder)
	-- increment the counter
	set new_folder_num to top_folder_count + 1
	-- convert the counter to a 3-digit string with leading 0s
	set new_folder_prefix to characters -3 through end of ("00" & new_folder_num) as text
	
	-- now we have everything we need
	-- so work out the new folder name
	set new_folder_name to new_folder_prefix & "_" & _name
	try
		-- try to create the new top-level folder
		set the_new_folder to make new folder at base_folder with properties {name:new_folder_name}
		-- and iterate 6 times
		repeat with i from 1 to 6
			-- and make each of the subfolders
			make new folder at the_new_folder with properties {name:_name & "_" & i as text}
		end repeat
	end try
	
end tell


How's that as a starting point?

Right now it's configured for a 'Capture' folder on your desktop, but you can edit the first line to define any folder you like (or integrate it into an Automator 'get Finder items' action.


Each time you run it, it creates a new set of 6 folders based on the count of folders and the name provided.


Also right now the logic is weak - it simply counts the number of folders and increments that. It doesn't look to see if those folders follow the 'leading counter', so if there were folders "001_foo", "002_bar", "other stuff" and "junk", the new folder would be 005 because there are 4 existing folders, even though 2 of them don't follow the naming convention. It can be made to work, but I need more coffee for that, and it might not be needed, depending on your discipline around folder names.

Jan 4, 2021 10:41 AM in response to Camelot

This is great and doing exactly what I hoped, but the part that I can't figure out is how to make the directory path dynamic. For the sake of simplicity in the question the folder just lived in a generic desktop folder, but if I wanted to make it nested I can't figure out how to set it to the correct path. Like for instance, in terminal I would point it to "~/sbx\ digital\ jobs/JOBNAME/Capture" but don't understand how to do that in an apple script.


Specifically, it would be on this line:


set base_folder to folder "Capture" of (path to desktop)


Does it need to be a POSIX path?

Jan 4, 2021 4:23 PM in response to deej668

> Now to figure out how to assign the working directory as a variable to make it more dynamic.


What's your definition of 'working directory' in this case?


AppleScripts aren't like shell scripts in that there's the current working directory where the shell is pointing to, nor is there a $PATH.


So the answer really hinges on how you expect to invoke the script, and how much user interaction you want.


For example, the script could look at the Finder and detect the current open window and decide that this is the 'working directory'.

Or the script could function as a droplet so you drop a folder onto the script icon to have it process that folder

Or it could be written as a service, so it's invoked via ctrl-click on a folder in the Finder

Or it could be written as a folder action, so it's inherently associated with a folder and is invoked any time new files are added to the folder.

Or it could prompt the user for which folder to work on.

Or it could do any combination of the above. It's all up to you and how you want the script to work.

Jan 4, 2021 4:55 PM in response to deej668

> I never realized you could run it as a service on a ctrl-click


From here it's a pretty easy change.


You can pretty much copy everything except the first action into a new workflow of the 'Quick Action' type.


When you create a 'Quick Action', you can nominate what kind of data the workflow expects, and in which apps - just set it to Folders in the Finder and you're set.

Automator: Making folders with an incremental counter prefix

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.