Based on the CSV file and Image Folder as inputs, this AppleScript application will use the new namestring field in the CSV as the filename (partial) replacement string, and then rename the image files in the same folder. Recommend that you make a test CSV that matches a test Image folder, and test the script on that first.
You don't need to learn AppleScript, Objective-C, or Python to use this script.
Note: Other than CSV delimiters, the other bullets are possible, but costly in complexity, and code/test time. One can consult the Python csv module for more detail.
-- img_rename.applescript
--
-- Select CSV file, and folder containing files to rename (in that order)
-- Will automatically detect comma, semi-colon, and tab delimiters in CSV
-- Replacement strings in CSV will be applied, and folder's files renamed.
-- Assumptions: • CSV headers unsupported
-- • 2 columns of unquoted CSV content
-- -
--
-- Inputs: 1) CSV file, 2) Folder containing files to rename
-- Tested: OS X 10.11.6, macOS 10.12.1 with System Python 2.7.10
-- Version 1.0
-- VikingOSX, Nov. 20, 2016, Apple Support Communities
property ca : current application
property default_loc : "~/Desktop"
property file_types : {"public.comma-separated-values-text", "public.plain-text"}
use framework "AppKit"
use AppleScriptversion "2.4" -- Yosemite or later
use scripting additions
on run
set alert_msg to "This script must be run from the main thread." & return & "Either press control+command+R to run it, or save it as a script or application."
-- check we are running in foreground
if not (ca'sNSThread'sisMainThread()) as boolean then
display alertalert_msgbuttons {"Cancel"} ascritical
error number -128
end if
set openstuff to getfiles("POSIX") as list
tell application "Finder"
set fileCnt to number of files in folder ((last item of openstuff) as POSIX file)
end tell
if fileCnt = 0 then
display dialog "Empty Folder specified."
return
end if
set args to (first item of openstuff) & space & (last item of openstuff)'s quoted form
set status to rename_files(args) as text
display dialogstatus
return
end run
on getfiles(afmt)
-- custom choose file(s) and folder(s). Can return POSIX, or HFS format styles
set Msg to "Select CSV file, and then with command-key, select Folder."
set returnCode to 0 as integer
if default_loc starts with "~" or adir starts with "../" then
-- relative POSIX paths to standard paths conversion
set tpath to ca'sNSString'sstringWithString:default_loc
set stdpath to tpath'sstringByStandardizingPath() as text
end if
-- custom file chooser
set oPanel to ca'sNSOpenPanel'sopenPanel()
tell oPanel
its setFloatingPanel:true -- over the top of all other windows
its setDirectoryURL: (POSIX filestdpath)
its setFrame: (ca'sNSMakeRect(0, 0, 720, 525)) display:yes
its setTitle:"Open"
its setMessage:Msg
its setPrompt:"Select"
its setAllowsMultipleSelection:true
its setAllowedFileTypes:file_types
its setCanChooseFiles:true
its setCanChooseDirectories:true
its setTreatsFilePackagesAsDirectories:false
end tell
set returnCode to oPanel'srunModal()
if returnCode is (ca'sNSFileHandlingPanelCancelButton) then
error number -128
end if
-- set the POSIXpaths to (oPanel's |URL|()'s valueForKey:"path") as list
if afmt is "HFS" then
return (oPanel's URLs) as list
else if afmt is "POSIX" then
return (oPanel's filenames()) as list
else
-- neither is not an option, force user cancel
error number -128
end if
return
end getfiles
on rename_files(vargs)
-- Read CSV file containing current and replacement filename strings.
-- Rename files in specified folder (not sub-folders) to replacement syntax.
return do shell script "python <<'EOF' - " & vargs & "
#!/usr/bin/python
# coding: utf-8
import csv
import os
import sys
csvdelim = ',;:|\\t'
if not len(sys.argv) == 3:
print 'Invalid argument list'
sys.exit(1)
csvfile, folder = map(str, [a.decode('utf-8') for a in sys.argv[1:]])
if not (os.path.isfile(csvfile) and os.path.isdir(folder)):
print 'Either CSV or Folder is missing'
sys.exit(1)
names_file = os.path.expanduser(csvfile)
f = os.path.expanduser(folder)
#if not os.listdir(f):
# print 'Folder is empty'
# sys.exit(1)
# no .DS_Store files
flist = sorted(filter(lambda f: not f.startswith('.'), os.listdir(f)))
t = ()
# read the CSV and make a tuple of tuples from the rows/columns
# e.g. (('old', 'new'), ('old', 'new'), ...)
with open(names_file, 'rb') as xcsv:
# automatically detect CSV delimiter if in csvdelim variable
try:
dialect = csv.Sniffer().sniff(xcsv.read(), delimiters=csvdelim)
except csv.Error as e:
print('{} - {}'.format(str(type(e)), str(e.args)))
sys.exit(1)
xcsv.seek(0)
thedata = csv.reader(xcsv, dialect)
for row in thedata:
t += ((row[0], row[1],),)
# make new list of files with replacement names
newfiles = [reduce(lambda s, kv: s.replace(*kv), t, x) for x in flist]
# change directory to target directory and do renames
os.chdir(f)
for i in range(0, len(flist)):
os.rename(flist[i], newfiles[i])
print('Done')
EOF"
end rename_files
I copy/pasted the above script back into Script Editor from this page, and it ran correctly.