Here are the announced tests.
(1) version using only vanilla code
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
on extractNumber(txt)
set listChars to text items of txt
set maybe to ""
repeat with i from 1 to count listChars
if item i of listChars is in "0123456789" then exit repeat
end repeat
repeat with j from i to count listChars
if item j of listChars is not in "0123456789" then exit repeat
set maybe to maybe & item j of listChars
end repeat
return maybe
end extractNumber
set sourceContainer to path to desktop as text
set sourceFolder to sourceContainer & "source:"
set destContainer to path to documents folder as text
set evenFolder to destContainer & "even:" # pair
set oddFolder to destContainer & "odd:" # impair
tell application "System Events"
# Create the destination folders if they aren't available
if not (exists folder evenFolder) then make new folder at end of folder destContainer with properties {name:"even"}
if not (exists folder oddFolder) then make new folder at end of folder destContainer with properties {name:"odd"}
# Grab the name of visibles files in the source folder
set beg to current application's NSDate's |date|()
repeat 100 times
set fileNames to name of disk items of folder sourceFolder whose visible is true
--log fileNames
repeat with aName in fileNames
# Extract the first possible number embedded in the file name
set maybe to my extractNumber(aName)
# Don't move files whose name doesn't embed a number
if (maybe is not "") and maybe as number ≤ 200 then
--log maybe
set maybe to (maybe as number) mod 2
if maybe = 1 then # move files embedding an odd number
--move disk item (sourceFolder & aName) to folder oddFolder
else # move files embedding an even number
--move disk item (sourceFolder & aName) to folder evenFolder
end if
end if
end repeat
end repeat
end tell # System Events
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,339022994041 second"
(2) version using ASObjC code to read extract the list of files but vanilla code to extract the embedded numbers.
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
on extractNumber(txt)
set listChars to text items of txt
set maybe to ""
repeat with i from 1 to count listChars
if item i of listChars is in "0123456789" then exit repeat
end repeat
repeat with j from i to count listChars
if item j of listChars is not in "0123456789" then exit repeat
set maybe to maybe & item j of listChars
end repeat
return maybe
end extractNumber
set sourceContainer to path to desktop as text
set sourceFolder to POSIX path of (sourceContainer & "source:")
set destContainer to path to documents folder as text
set evenFolder to destContainer & "even:" # pair
set oddFolder to destContainer & "odd:" # impair
tell application "System Events"
# Create the destination folders if they aren't available
if not (exists folder evenFolder) then make new folder at end of folder destContainer with properties {name:"even"}
if not (exists folder oddFolder) then make new folder at end of folder destContainer with properties {name:"odd"}
# Grab the name of visibles files in the source folder
set beg to current application's NSDate's |date|()
repeat 100 times
set fileManager to current application's NSFileManager's defaultManager()
set directoryContents to fileManager's contentsOfDirectoryAtPath:sourceFolder |error|:(missing value)
set fileNames to directoryContents as list
--log fileNames
repeat with aName in fileNames
# Extract the first possible number embedded in the file name
set maybe to my extractNumber(aName)
# Don't move files whose name doesn't embed a number
if (maybe is not "") and maybe as number ≤ 200 then
--log maybe
set maybe to (maybe as number) mod 2
if maybe = 1 then # move files embedding an odd number
--move disk item (sourceFolder & aName) to folder oddFolder
else # move files embedding an even number
--move disk item (sourceFolder & aName) to folder evenFolder
end if
end if
end repeat
end repeat
end tell # System Events
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,095301985741 second"
(3) version extracting the list of files with ASObjC code, filtering them with ASObjC code using Regex
use framework "Foundation"
use scripting additions
--set sourceFolder to POSIX path of (choose folder)
set sourceContainer to path to desktop as text
set sourceFolder to POSIX path of (sourceContainer & "source:")
set beg to current application's NSDate's |date|()
repeat 100 times
set fileManager to current application's NSFileManager's defaultManager()
set directoryContents to fileManager's contentsOfDirectoryAtPath:sourceFolder |error|:(missing value)
set oddPredicate to current application's NSPredicate's predicateWithFormat:"SELF matches '.*[^0-9]1?[0-9]?[13579][^0-9/][^/]*'"
set oddResults to directoryContents's filteredArrayUsingPredicate:oddPredicate
set evenPredicate to current application's NSPredicate's predicateWithFormat:"SELF matches '.*[^0-9](1?[0-9][02468]|[2468]|200)[^0-9/][^/]*'"
set evenResults to directoryContents's filteredArrayUsingPredicate:evenPredicate
end repeat
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,046254992485 second"
log oddResults as list
log evenResults as list
So, we may see that the greater reduction of duration is due to the replacement of vanilla code by ASObjC one to extract the list of files.
At least two complementary tests were possible :
(a) one using list file to extract the filenames but I dropped here because list files is deprecated for years
(b) one using the Finder as an alternative to System Events but as you certainly know, I dislike the Finder which most of the time is slower than System Events.
As you know, I’m really curious so I didn’t resisted to make other tests.
This time the scripts really moved the files which I moved back after each run.
(I) ASObjC code to get the names, vanilla to extract numbers.
I ran it twice.
First with dest folders defined as string, last with the dest folders defined as aliases.
I was surprised to see that using aliases is a slowdowner.
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
on extractNumber(txt)
set listChars to text items of txt
set maybe to ""
repeat with i from 1 to count listChars
if item i of listChars is in "0123456789" then exit repeat
end repeat
repeat with j from i to count listChars
if item j of listChars is not in "0123456789" then exit repeat
set maybe to maybe & item j of listChars
end repeat
return maybe
end extractNumber
set sourceContainer to path to desktop as text
set sourceFolder to POSIX path of (sourceContainer & "source:")
set destContainer to path to documents folder as text
set evenFolder to destContainer & "even:" # pair
set oddFolder to destContainer & "odd:" # impair
tell application "System Events"
# Create the destination folders if they aren't available
if not (exists folder evenFolder) then make new folder at end of folder destContainer with properties {name:"even"}
if not (exists folder oddFolder) then make new folder at end of folder destContainer with properties {name:"odd"}
--set evenFolder to evenFolder as alias # pair
--set oddFolder to oddFolder as alias # impair
# Grab the name of visibles files in the source folder
set beg to current application's NSDate's |date|()
set fileManager to current application's NSFileManager's defaultManager()
set directoryContents to fileManager's contentsOfDirectoryAtPath:sourceFolder |error|:(missing value)
set fileNames to directoryContents as list
--log fileNames
repeat with aName in fileNames
# Extract the first possible number embedded in the file name
set maybe to my extractNumber(aName)
# Don't move files whose name doesn't embed a number
if (maybe is not "") and maybe as number ≤ 200 then
--log maybe
set maybe to (maybe as number) mod 2
if maybe = 1 then # move files embedding an odd number
move disk item (sourceFolder & aName) to folder oddFolder
else # move files embedding an even number
move disk item (sourceFolder & aName) to folder evenFolder
end if
end if
end repeat
end tell # System Events
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,021662950516 second"
--> "Done in : 0,027228951454 second" if the folder are predefined as aliases
(II) ASObjC to grab the names, ASObjC to apply regex to filter
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
--set sourceFolder to POSIX path of (choose folder)
set sourceContainer to path to desktop as text
set sourceFolder to POSIX path of (sourceContainer & "source:")
set destContainer to path to documents folder as text
set evenFolder to destContainer & "even:" # pair
set oddFolder to destContainer & "odd:" # impair
tell application "System Events"
# Create the destination folders if they aren't available
if not (exists folder evenFolder) then make new folder at end of folder destContainer with properties {name:"even"}
if not (exists folder oddFolder) then make new folder at end of folder destContainer with properties {name:"odd"}
end tell
set beg to current application's NSDate's |date|()
set fileManager to current application's NSFileManager's defaultManager()
set directoryContents to fileManager's contentsOfDirectoryAtPath:sourceFolder |error|:(missing value)
set oddPredicate to current application's NSPredicate's predicateWithFormat:"SELF matches '.*[^0-9]1?[0-9]?[13579][^0-9/][^/]*'"
set oddResults to directoryContents's filteredArrayUsingPredicate:oddPredicate
set evenPredicate to current application's NSPredicate's predicateWithFormat:"SELF matches '.*[^0-9](1?[0-9][02468]|[2468]|200)[^0-9/][^/]*'"
set evenResults to directoryContents's filteredArrayUsingPredicate:evenPredicate
tell application "System Events"
repeat with aName in (oddResults as list)
move file (sourceFolder & aName) to folder oddFolder
end repeat
repeat with aName in (evenResults as list)
move file (sourceFolder & aName) to folder evenFolder
end repeat
end tell
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,020846009254 second"
(III) shell script to extract odd and even items, System Events to move them
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
(*
set sourceFolder to (choose folder with prompt "Select the source folder.")
set evensFolder to (choose folder with prompt "Select the folder for files with even numbers in their names.")
*)
set sourceContainer to path to desktop as text
set sourceFolder to POSIX path of (sourceContainer & "source:")
set destContainer to path to documents folder as text
set evenFolder to (destContainer & "even:") # pair
set oddFolder to (destContainer & "odd:") # impair
set beg to current application's NSDate's |date|()
-- Find files with names containing even numbers ” ie. whose POSIX paths contain an even digit followed by a non-digit which is not "/" and with no further "/"s in the path.
set evens to paragraphs of (do shell script "find -E " & quoted form of POSIX path of sourceFolder & " -maxdepth 1 -regex '.*[^0-9](1?[0-9][02468]|[2468]|200)[^0-9/][^/]*'")
set odds to paragraphs of (do shell script "find -E " & quoted form of POSIX path of sourceFolder & " -maxdepth 1 -regex '.*[^0-9]1?[0-9]?[13579][^0-9/][^/]*'")
tell application "System Events"
repeat with thisFile in evens
move file thisFile to folder evenFolder
end repeat
repeat with thisFile in odds
move file thisFile to folder oddFolder
end repeat
end tell
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,058142006397 second"
(IV) everything with do shell script
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
(*
set sourceFolder to (choose folder with prompt "Select the source folder.")
set evensFolder to (choose folder with prompt "Select the folder for files with even numbers in their names.")
*)
set sourceContainer to path to desktop as text
set sourceFolder to quoted form of POSIX path of (sourceContainer & "source:")
set destContainer to path to documents folder as text
set evenFolder to quoted form of POSIX path of (destContainer & "even:") # pair
set oddFolder to quoted form of POSIX path of (destContainer & "odd:") # impair
set beg to current application's NSDate's |date|()
-- Find files with names containing even numbers ” ie. whose POSIX paths contain an even digit followed by a non-digit which is not "/" and with no further "/"s in the path.
set evens to paragraphs of (do shell script "find -E " & sourceFolder & " -maxdepth 1 -regex '.*[^0-9](1?[0-9][02468]|[2468]|200)[^0-9/][^/]*'")
set odds to paragraphs of (do shell script "find -E " & sourceFolder & " -maxdepth 1 -regex '.*[^0-9]1?[0-9]?[13579][^0-9/][^/]*'")
repeat with thisFile in evens
do shell script "mv " & quoted form of thisFile & " " & evenFolder
end repeat
repeat with thisFile in odds
do shell script "mv " & quoted form of thisFile & " " & oddFolder
end repeat
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,117416977882 second"
The result was so bad that I decided to replace the final loops by a more Unix aware scheme.
(V) This time, the groups of quoted forms of pathnames are moved in a single call.
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
(*
set sourceFolder to (choose folder with prompt "Select the source folder.")
set evensFolder to (choose folder with prompt "Select the folder for files with even numbers in their names.")
*)
set sourceContainer to path to desktop as text
set sourceFolder to quoted form of POSIX path of (sourceContainer & "source:")
set destContainer to path to documents folder as text
set evenFolder to quoted form of POSIX path of (destContainer & "even:") # pair
set oddFolder to quoted form of POSIX path of (destContainer & "odd:") # impair
set beg to current application's NSDate's |date|()
-- Find files with names containing even numbers ” ie. whose POSIX paths contain an even digit followed by a non-digit which is not "/" and with no further "/"s in the path.
set evens to paragraphs of (do shell script "find -E " & sourceFolder & " -maxdepth 1 -regex '.*[^0-9](1?[0-9][02468]|[2468]|200)[^0-9/][^/]*'")
set odds to paragraphs of (do shell script "find -E " & sourceFolder & " -maxdepth 1 -regex '.*[^0-9]1?[0-9]?[13579][^0-9/][^/]*'")
set evensList to {}
repeat with thisFile in evens
set end of evensList to quoted form of thisFile
end repeat
set oddsList to {}
repeat with thisFile in odds
set end of oddsList to quoted form of thisFile
end repeat
do shell script "mv " & my recolle(evensList, " ") & " " & evenFolder
do shell script "mv " & my recolle(oddsList, " ") & " " & oddFolder
set theDiff to (beg's timeIntervalSinceNow()) as real # CAUTION, it's a negative value
set theDiff to -theDiff
if theDiff > 1 then
set maybe to " seconds"
else
set maybe to " second"
end if
tell application "SystemUIServer" to display dialog "Done in : " & theDiff & maybe
--> "Done in : 0,065730988979 second"
#=====
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
#=====
Ouf, that’s all folks.
So, the faster is the scheme using ASObjC to extract the filenames and filter them with regex.
But, as the difference is short, for my own use, if I have to apply a different filter I will try to build a vanilla one because for me, Regex is resembling to ancient Chinese.
Yvan KOENIG running Yosemite 10.10.5 in French (VALLAURIS, France) dimanche 27 septembre 2015 16:49:20