How to make this AppleScript faster and better

Here's what I've got so far.

I will use this script a lot and with huge amount of files, so I need it to be perfect.

Unfortunately I am nothing at this kind of stuff, so a help would be really appreciated.


property source_folder : alias "path:to:source_folder:" as string property tattoos_folder : alias "path:to:tattoos_folder:" as string property models_folder : alias "path:to:models_folder:" as string property names_text : alias "OS X:Users:bagrov:Desktop:test:names.txt" as stringprocess_folder(source_folder)

on
process_folder(this_folder)
set
these_items to list folderthis_folder without invisibles set container_name to name of (info forthis_folder)
repeat with
i from 1 to the count of these_items set this_item to alias ((this_folder as Unicode text) & (itemi of these_items))
if
folder of (info forthis_item) is true then
process_folder(this_item)
else
process_item(this_item, container_name, i)
end if
end repeat
end
process_folder-- this sub-routine processes files on process_item(this_item, c, i)
if
i < 10 then
set
i to "000" & i else if (i < 100) and (i > 9) then
set
i to "00" & i else if (i < 1000) and (i > 99) then
set
i to "0" & i end if

set
r to (random numberfrom 0 to 9999)
if
r < 10 then
set
r to "000" & r else if (r < 100) and (r > 9) then
set
r to "00" & r else if (r < 1000) and (r > 99) then
set
r to "0" & r end if

tell
application "System Events"
-- get file extension so not overwritten set e to name extension of this_item set new_name to "" & r & "" & c & "" & i & "." & e set name of this_item to new_name end tell
end
process_item try
set
names_list to paragraphs of (readfilenames_text)
tell
application "Finder"
set
item_list to (files of entire contents of foldersource_folder)
repeat with
this_item in item_list set item_name to name of this_item repeat with this_name in name_list if this_name is in item_name then
movethis_itemtofoldermodels_folder exit repeat
end if
end repeat
if
existsthis_item then movethis_itemtofoldertattoos_folder end repeat
end tell
end trydisplay notification "All images were processed." with title "New" sound name "Glass.aiff"

tell me to quit

I know that it's possible to make 'try' part better with shell. Finder won't get through 30,000-50,000 files.

Posted on Nov 12, 2015 12:18 PM

Reply
7 replies

Nov 13, 2015 2:28 AM in response to bagrov

Hello


You might replace your try block with the following code.



(* -- context memo property source_folder : "path:to:source_folder" property tattoos_folder : "path:to:tattoos_folder" property models_folder : "path:to:models_folder" property names_text : "path:to:names.txt" *) set args to "" repeat with a in {source_folder, tattoos_folder, models_folder, names_text} set args to args & (a as alias)'s POSIX path's quoted form & space end repeat do shell script "/bin/bash -s <<'EOF' - " & args & " SOURCE=$1 TATTOOS=$2 MODELS=$3 # $MODELS cannot be a descendant of $SOURCE NAMES=$4 # move files in $SOURCE whose name contains some name in $NAMES to $MODELS while read n do [[ -z \"$n\" ]] && continue # skip blank line find \"$SOURCE\" -type f -name \"*$n*\" -print0 | xargs -0 -J% mv % \"$MODELS\" done < <(awk '1' \"$NAMES\") # move rest of files in $SOURCE (except for dot files) to $TATTOOS find \"$SOURCE\" -type f ! -name '.*' -print0 | xargs -0 -J% mv % \"$TATTOOS\" EOF"



Regards,

H

Nov 14, 2015 3:25 AM in response to bagrov

Hello


You're welcome. 🙂

And if I understand you correctly, you might try something like the following code to handle additional destination per name list. In the following example, the files that are not moved to c1..c3 according to c1_names..c3_names are moved to c4.



set source to "path:to:source" set c1 to "path:to:category1" set c2 to "path:to:category2" set c3 to "path:to:category3" set c4 to "path:to:category4" set c1_names to "path:to:category1_names.txt" set c2_names to "path:to:category2_names.txt" set c3_names to "path:to:category3_names.txt" set args to "" repeat with a in {source, c1, c1_names, c2, c2_names, c3, c3_names, c4} set args to args & (a as alias)'s POSIX path's quoted form & space end repeat do shell script "/bin/bash -s <<'EOF' - " & args & " # # $1 : source_directory # $2.. : destination_1 list_1 ... destionation_n list_n destination_r # # - file in source_direcotry is moved to destination_k if the name containns some name in list_k for k = 1..n # - file in source_directory which has not been moved to destination_1..n is moved to destination_r if destination_r is given # - destination_i (i = 1..n, r) cannot be descendant of source_directory # - if there's no corresponding destination_k for list_k, list_i (i = k..n) is ignored. # - destination_k and list_k may be either interleaved or separated in arguments list # SOURCE=$1 DEST=() # array of destination directories LIST=() # array of name list files shift for a in \"$@\" do [[ -d $a ]] && DEST+=( \"$a\" ) [[ -f $a ]] && LIST+=( \"$a\" ) done # move files in $SOURCE whose name contains some name in ${LIST[i]} to ${DEST[i]} for (( i = 0; i < ${#LIST[@]}; i++ )) do [[ -z ${DEST[i]} ]] && break # break if no corresponding destination awk '1' \"${LIST[i]}\" | while read n do [[ -z \"$n\" ]] && continue # skip blank line find \"$SOURCE\" -type f -name \"*$n*\" -print0 | xargs -0 -J% mv % \"${DEST[i]}\" done done [[ -z ${DEST[i]} ]] && exit # exit if no destination left # move rest of files in $SOURCE (except for dot files) to ${DEST[i}} find \"$SOURCE\" -type f ! -name '.*' -print0 | xargs -0 -J% mv % \"${DEST[i]}\" EOF"




Briefly tested under OS X 10.6.8 but no warranties. Please make sure you have backup of directories and files before running this sort of script.


Good luck,

H

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

How to make this AppleScript faster and better

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