Folder creation script

Hi,

I was hoping somebody could help me with a script please,

I’am trying to create a script that creates a specific number of folders with specific names

For instance to create 50 folders named (TD-48-***) the last three digits acting as counter

TD-48-001
TD-48-002
TD-48-003


TD-48-

Any help would be hugely appreciated :smiley:

Hi there,
This should get you started:


tell application "Finder"
	
	repeat with i from 1 to 50
		set newFolder to (path to home folder from user domain) & "Desktop:foldersTest" as string
		make new folder at folder newFolder as text with properties {name:"TD-48-" & (text -3 thru -1 of ("000" & i))}
	end repeat

end tell

First of all create a folder on your desktop called ‘foldersTest’.
You can change the destination to whatever you require.

HTH

I would certainly not use the Finder.

set theFolder to (path to desktop as text) & "4see" # define it only once
tell application "System Events"
	repeat with i from 1 to 50
		make new folder at end of folder theFolder with properties {name:"TD-48-" & text -3 thru -1 of ((1000 + i) as text)}
	end repeat
end tell

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) mercredi 6 janvier 2016 16:04:02

Thanks for the improvement Yvan.
Even learnt a variation to adding leading zeros to a number.

I borrowed it from Nigel Garvey’s scripts.

For those which installed Shane Stanley’s FileManagerLib here is an alternate version :

use FMLib : script "FileManagerLib"
use scripting additions

set commonPart to (path to desktop as text) & "4see:TD-48-" # define it only once

repeat with i from 1 to 50
	(FMLib's createFolder:(commonPart & text -3 thru -1 of ((1000 + i) as text)))
end repeat

and an other one. I don’t know which one of these two is the fastest.

use FMLib : script "FileManagerLib"
use scripting additions

set theFolder to (path to desktop as text) & "4see:" # define it only once

repeat with i from 1 to 50
	(FMLib's createFolderNamed:("TD-48-" & text -3 thru -1 of ((1000 + i) as text)) inFolder:theFolder)
end repeat

Here is a version using ASObjC to build the three digits string.

use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use FMLib : script "FileManagerLib"


set theFolder to (path to desktop as text) & "4see:" # define it only once

repeat with i from 1 to 50
	set theName to "TD-48-" & (my formatNumber:i usingFormat:"000")
	(FMLib's createFolderNamed:theName inFolder:theFolder)
end repeat

-- Simple number formatter

on formatNumber:theNumber usingFormat:formatString
	set theFormatter to current application's NSNumberFormatter's new()
	theFormatter's setFormat:formatString
	theFormatter's setLocalizesFormat:false
	set theResult to theFormatter's stringFromNumber:theNumber
	return theResult as text
end formatNumber:usingFormat:

We may use an other way to do the job :

use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"
use FMLib : script "FileManagerLib"

property theNSNumberFormatter : missing value
on formatNumber:n
	if my theNSNumberFormatter = missing value then
		-- mkae a date formatter
		set my theNSNumberFormatter to current application's NSNumberFormatter's alloc()'s init()
		tell my theNSNumberFormatter -- configure the formatter
			its setMinimumIntegerDigits:3
		end tell
	end if
	-- tell the formatter to format the number
	return (theNSNumberFormatter's stringFromNumber:n) as text
end formatNumber:


set theFolder to (path to desktop as text) & "4see:" # define it only once

repeat with i from 1 to 50
	set theName to "TD-48-" & (my formatNumber:i)
	(FMLib's createFolderNamed:theName inFolder:theFolder)
end repeat

Both may be interesting if the used handler is already available in an installed library.
Here we just have two samples of ASObjC use.
A day during which I learn something is a good day and given what we see here and there in this foolish world, it’s fine to have some.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) mercredi 6 janvier 2016 18:01:37

And here’s one more, using both FileManagerLib and BridgePlus

use scripting additions
use framework "Foundation"
use script "BridgePlus"
use FMLib : script "FileManagerLib"

load framework
set theFolder to (path to desktop as text) & "4see:" # define it only once
set theList to current application's SMSForder's arrayWithPattern:"TD-48-%@" startNumber:1 endNumber:50 minDigits:3
repeat with aName in theList
	(FMLib's createFolderNamed:(aName as text) inFolder:theFolder)
end repeat

Thanks Shane.
I’m scrapping my head with no result.

I’m trying to format a phone number by groups of two digits.
At this time I am able to do it on my machine running in French

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

set thePhone to "0987654321" as number
my formatNumber:thePhone usingFormat:"00,00,00,00,00"
# Want to get : 09 87 65 43 21

-- Simple number formatter

on formatNumber:theNumber usingFormat:formatString
	set theFormatter to current application's NSNumberFormatter's new()
	theFormatter's setFormat:formatString
	theFormatter's setLocalizesFormat:false
	set theResult to theFormatter's stringFromNumber:theNumber
	return theResult as text
end formatNumber:usingFormat:

It works here because the local separator for groups of digits is a blank character.
As in English the separator is the comma, I guess that the given script would return 09,87,65,43,21 on a machine running in English.
How may I get groups of two digits (with leading zero if needed) separated by spaces everywhere ?
I looked in Unicode Technical Standard #35 but it didn’t help.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) jeudi 7 janvier 2016 17:22:01

Oddly enough, treating phone numbers as numbers generally doesn’t work out well. But in this case, because the pattern is regular, it’s pretty easy:

on formatFrenchPhoneNumber:theNumber
	set theFormatter to current application's NSNumberFormatter's new()
	theFormatter's setGroupingSeparator:space
	theFormatter's setGroupingSize:2
	theFormatter's setUsesGroupingSeparator:true
	theFormatter's setMinimumIntegerDigits:10
	set theResult to theFormatter's stringFromNumber:theNumber
	return theResult as text
end formatFrenchPhoneNumber:

But normal phone number formatting is usually done by text parsing.

Thanks Shane

I had one of your samples :

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

-- Simple number formatter
property theNSNumberFormatter : missing value
on formatNumber:n
	if my theNSNumberFormatter = missing value then
		-- mkae a date formatter
		set my theNSNumberFormatter to current application's NSNumberFormatter's alloc()'s init()
		tell my theNSNumberFormatter -- configure the formatter
			its setLocale:(current application's NSLocale's alloc()'s initWithLocaleIdentifier:"fr")
			its setNumberStyle:(current application's NSNumberFormatterDecimalStyle)
			its setMinimumFractionDigits:1
			its setMaximumFractionDigits:5
			its setMinimumIntegerDigits:1
			its setRoundingMode:(current application's NSNumberFormatterRoundHalfUp)
			its setHasThousandSeparators:false
		end tell
	end if
	-- tell the formatter to format the number
	return (theNSNumberFormatter's stringFromNumber:n) as text
end formatNumber:

but when I searched in Xcode help, I found a list of properties like :
groupingSeparator
usesGroupingSeparator
thousandSeparator
hasThousandSeparators
decimalSeparator
alwaysShowsDecimalSeparator
currencyDecimalSeparator
groupingSize
secondaryGroupingSize

paddingCharacter
paddingPosition

minimumIntegerDigits
minimumFractionDigits
maximumIntegerDigits
maximumFractionDigits

but I didn’t guess the syntax : setgroupingSeparator:space
I just thought that the ones which you used were defined elsewhere. ;-(

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) vendredi 8 janvier 2016 11:09:48

Yvan,

when properties in Objective-C are synthesized they implicitly provide a getter ivar and a setter setIvar (note the capital I) which can be used beside the recommended dot notation object.ivar this way: [object ivar] and [object setIvar:value].

Since dot notation is not supported in AppleScriptObjC you have to use the implicit getter/setter.

Thanks Stefan

My old brain will try to memorize that.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) vendredi 8 janvier 2016 12:19:56

Hi.

There’s quite a simple way to do this (one you understand it!) using a shell script:

-- This creates fifty folders with the name sequence "TD-48-001" to "TD-48-050" in a folder called "Fred" on the desktop.

set rootPath to quoted form of POSIX path of ((path to desktop as text) & "Fred:")
do shell script ("mkdir -p " & rootPath & "TD-48-0{0{1..9},{10..50}}")

(* Notes:
	1. mkdir's -p option creates the folders in the root path too if they don't already exist.
	2. The leading zeros in the number sequence have to be written into the expansion code. The first zero in the mkdir line above appears in all the numbers; the second only in the single-digit numbers 1 to 9.
*)

Thanks for sharing that Nigel, it’s pretty quick.

Out of curiosity I pushed it a bit further…


do shell script ("mkdir -p " & rootPath & "TD-48-{000{1..9},00{10..99},0{100..999},{1000..5000}}")

… and it’s still really quick. I did try 9999 but then you get the error Argument list too long.
Can’t think of many instances where I’ll need to create that many folders though.

I don’t know if it’s always been the case, but these days at least you don’t have to. For example, this works fine too:

on formatFrenchPhoneNumber:theNumber
	set theFormatter to current application's NSNumberFormatter's new()
	set theFormatter's groupingSeparator to space
	set theFormatter's groupingSize to 2
	set theFormatter's usesGroupingSeparator to true
	set theFormatter's minimumIntegerDigits to 10
	set theResult to theFormatter's stringFromNumber:theNumber
	return theResult as text
end formatFrenchPhoneNumber:

I prefer the setCap style, probably partly from habit, but also for the better syntax formatting.

Offtopic: Dot notation is not recommended by everyone, Apple uses it in their example codes but their example codes are not always well thought thru and are made in a hurry to get developers work with their code as soon as possible. In C dot notations are always assignments, you know exactly what it does. Since Objective-C 2.0 dot notation can mean accessing a struct or sending an message. I prefer that my code is self explanatory and many will agree, like the folks at Big Nerd Ranch. Adding dot notation was adding another flaw to the language rather than a nice feature.

It’s supporting AppleScript notation, not dot notation. Simply said, there is no distinction between dot notation or not at runtime :slight_smile:

You may do the job with two calls :wink:

set rootPath to quoted form of POSIX path of ((path to desktop as text) & "4see:")

do shell script ("mkdir -p " & rootPath & "TD-48-0{00{1..9},0{10..99},{100..999}}")
do shell script ("mkdir -p " & rootPath & "TD-48-{1000..5000}")

Creating the folders was faster than deleting them using the Finder.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) vendredi 8 janvier 2016 15:18:35

In fact the formatting is neater when we use ASObjC Explorer which put setGroupingSeparator and similar objects in red.
When we use Script Editor, the difference is not evident.

Yvan KOENIG running El Capitan 10.11.2 in French (VALLAURIS, France) vendredi 8 janvier 2016 15:23:08

It’s a matter of habit and taste.

Although it might be not “terminological correct” dot notation is very convenient and a time saver.
When you switch to Swift you’ll notice this huge square bracket overhead (not only that) of Objective-C using the standard notation.

I’m not sure anyone said AppleScript was supporting dot notation. But treating Objective-C properties as properties in AppleScript – either by omitting the parentheses from accessors or using the property name with AppleScript’s set – does result in different behavior at runtime, with properties handled directly by key-value coding. In the case of accessors, the results can be different because the result type of a KVC call is id.