Is there a way to make this script using “System Events”?

I have this great piece of script.

What it does is it processes the folder, looks in cats_names.txt and if it finds a picture that contains name from this .txt file it will move it to cats_folder. All other pics go to dogs folder. Later I’ll have more folders and lists (parrots + names, fishes + names etc).

I just processed 40,000 files in it took about 20 minutes. Is there a way to somehow use System Events or something similar to it? Because I guess that shell part makes it so slow. I cannot even think how long would Finder take to make the same job.

Also I think something in the script is wrong. It assigned name of folder to all the files in it and moved it to right different folders, but also it moved 5x more photos that I actually had to one of folders.

property source_folder : alias "path:to:source_folder"
property dogs_folder : alias "path:to:dogs_folder"
property cats_folder : alias "path:to:cats:folder"
property cats_list : alias "path:to:cats_names.txt" as string

process_folder(source_folder)

on process_folder(this_folder)
    set these_items to list folder this_folder without invisibles
    set container_name to name of (info for this_folder)
    repeat with i from 1 to the count of these_items
        set this_item to alias ((this_folder as Unicode text) & (item i of these_items))
        if folder of (info for this_item) is true then
            process_folder(this_item)
        else
            process_item(this_item, container_name, i)
        end if
    end repeat
end process_folder

on process_item(this_item, c, i)

    set i to text -4 thru -1 of ((10000 + i) as text)
    set r to (random number from 0 to 9999)
    set r to text -4 thru -1 of ((10000 + r) as text)

    tell application "System Events"
        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

set args to ""
#repeat with a in {folder_1 list_1 ... folder_n list_n, dogs}
repeat with a in {source_folder, cats_folder, cats_list, dogs_folder}
    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 ... destination_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"

display notification "All images were processed." with title "New" sound name "Glass.aiff"
tell me to quit

By the way System Events’ move command will work in this script if you put it somewhere in the ‘on process_item’.