Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Bulk renaming portion of files using automator workflow and csv file

Hey Guys,


I have been trying to use Automator to rename portions of 300 files names. I can use the find and replace on finder but I will have to do it for 200 files. I copied this code from https://discussions.apple.com/thread/251756941. However, I do not know how to adapt the code to find and replace the portions. So I want to replace only sections of the filename. Assistance will be appreciated?


Test csv data:


The file names below:



Automator workflow:




The code that needs updating:


DIR="$1"

shift

CSV="$1"


# unnecessary, but if the CSV file doesn't exist, exit

# [[ -s "$CSV" ]] || exit 1


cd "${DIR}"


# works with comma delimited CSV

while IFS=',' read oldfile newfile

do

# do not process headings

[[ ! "${oldfile}" =~ \.(jpg|jpeg|png)$ ]] && continue


# Skip entry if old filename in CSV doesn't exist in current folder

[[ -e "${oldfile}" ]] || continue


# strip any trailing empty comma delimiters from end of newfile

newfilex="${newfile//,/}"

# replace any detected illegal forward slash with an underscore

newfilex="${newfilex//\//_}"


# rename files

/bin/mv "${oldfile}" "${newfilex}"

# remove any double-quoted items and if from Windows, trim the CR from the line

done < <(sed -e 's/"//g;' "${CSV}" | tr -d '\r')

# done < "${CSV}"


sleep 1

/usr/bin/osascript -e 'display dialog "Processing complete."' &> /dev/null

exit 0

MacBook Pro 15″, macOS 11.0

Posted on Mar 4, 2021 8:42 AM

Reply
Question marked as Best reply

Posted on Mar 8, 2021 1:26 PM

I created a CSV using your example, and for each old file basename, I created 50 numerical suffix variations of it in a folder. Thus, 250 test files for 5 CSV rows. You would put your CSV file in the same folder as the images with the name of data.csv.


From /Applications folder, launch Automator. Choose New document, Application, and click Choose. Now, you will need two library actions dragged and dropped onto the larger workflow window in the following order:

  1. Files and Folders Library > Ask for Finder Items
    1. Start At: Desktop
    2. Type: Folder (do not check Allow multiple selection)
  2. Utilities Library > Run Shell Script
    1. Shell: /bin/zsh
    2. Pass input: as arguments
    3. Select and remove all default boilerplate script in this action, as it will be replaced by the following script code
  3. Paste the following script code into the Run Shell Script action
  4. Save the Application to your Desktop
  5. Quit Automator


Script Code for the Run Shell Script action


#!/bin/zsh

: <<'COMMENT'
Given a folder containing the data.csv file, rename every image basename
to the newfile name, retaining the original suffix format of the oldfile.

Example: SS1234_5.jpg -> T83_KK_5.jpg

Usage: csv.zsh foldername
Reference: https://discussions.apple.com/thread/252521799
Tested: macOS 11.2.2, zsh v5.8
Author: VikingOSX, 2021-03-08, Apple Support Communities, no warranties
COMMENT

typeset -a files=()

SDIR="${1:a:s/\~\//}"
[[ -d $SDIR ]] || exit 1
cd "${SDIR}"
CSV="data.csv"
[[ -s $CSV ]] || exit 1

# assumption that the CSV separator is a comma
while IFS=',' read oldfile newfile
do
    # skip CSV header if present
    [[ "$oldfile" == "oldfile" ]] && continue

    # get all case-insensitive instances of oldfile into an array
    setopt no_CASE_GLOB
    files=( "$oldfile"_*.(jpg|jpeg)(.N) )

    # each oldfile instance will have it's basename replaced by newfile
    # while retaining the respective oldfile suffix and extension.
    for f in $files;
    do 
        # capture () the current oldfile suffix and extension into match array
        [[ $f =~ '^[A-Z0-9]+(_.*)$' ]] || continue
        # rename using newfile basename with oldfile suffix
        mv "${f}" "${newfile}$match[1]"
    done
    files=()
    # ensure there are no quoted CSV elements, or any CR line endings
done < <(sed -e 's/"//g;' "${CSV}" | tr -d '\r')
unset files
exit 0


Similar questions

11 replies
Question marked as Best reply

Mar 8, 2021 1:26 PM in response to SamSpring

I created a CSV using your example, and for each old file basename, I created 50 numerical suffix variations of it in a folder. Thus, 250 test files for 5 CSV rows. You would put your CSV file in the same folder as the images with the name of data.csv.


From /Applications folder, launch Automator. Choose New document, Application, and click Choose. Now, you will need two library actions dragged and dropped onto the larger workflow window in the following order:

  1. Files and Folders Library > Ask for Finder Items
    1. Start At: Desktop
    2. Type: Folder (do not check Allow multiple selection)
  2. Utilities Library > Run Shell Script
    1. Shell: /bin/zsh
    2. Pass input: as arguments
    3. Select and remove all default boilerplate script in this action, as it will be replaced by the following script code
  3. Paste the following script code into the Run Shell Script action
  4. Save the Application to your Desktop
  5. Quit Automator


Script Code for the Run Shell Script action


#!/bin/zsh

: <<'COMMENT'
Given a folder containing the data.csv file, rename every image basename
to the newfile name, retaining the original suffix format of the oldfile.

Example: SS1234_5.jpg -> T83_KK_5.jpg

Usage: csv.zsh foldername
Reference: https://discussions.apple.com/thread/252521799
Tested: macOS 11.2.2, zsh v5.8
Author: VikingOSX, 2021-03-08, Apple Support Communities, no warranties
COMMENT

typeset -a files=()

SDIR="${1:a:s/\~\//}"
[[ -d $SDIR ]] || exit 1
cd "${SDIR}"
CSV="data.csv"
[[ -s $CSV ]] || exit 1

# assumption that the CSV separator is a comma
while IFS=',' read oldfile newfile
do
    # skip CSV header if present
    [[ "$oldfile" == "oldfile" ]] && continue

    # get all case-insensitive instances of oldfile into an array
    setopt no_CASE_GLOB
    files=( "$oldfile"_*.(jpg|jpeg)(.N) )

    # each oldfile instance will have it's basename replaced by newfile
    # while retaining the respective oldfile suffix and extension.
    for f in $files;
    do 
        # capture () the current oldfile suffix and extension into match array
        [[ $f =~ '^[A-Z0-9]+(_.*)$' ]] || continue
        # rename using newfile basename with oldfile suffix
        mv "${f}" "${newfile}$match[1]"
    done
    files=()
    # ensure there are no quoted CSV elements, or any CR line endings
done < <(sed -e 's/"//g;' "${CSV}" | tr -d '\r')
unset files
exit 0


Mar 4, 2021 9:06 AM in response to SamSpring

You appear to have a different filename in the oldfile CSV column than the reality of what you show in your Finder listing.

  1. Can there be multiple filenames with the same basename (e.g. SS1234) but with different suffixes (e.g. _1, _2, _n)?
  2. Is there just a unique file named SS1234.jpg with no suffix, and it is these that you want to be renamed?


You mention you want to replace only sections of filenames? Explain with an example using from existing filename -> to a final filename. This is a different problem than what the script you attempted to adopt performs as it would involve finding and changing substrings.

Mar 8, 2021 12:56 AM in response to VikingOSX

Hi VikingOSX,


Thanks for the reply.


  1. Yes, there are multiple filenames with the same basename and different suffixes.
  2. There is no unique filename. All of them have suffix.



Examples of how i want to change the names..

existing filename -> final filename

SS1234_1..jpg -> T83_KK_1..jpg

SS1234_2..jpg -> T83_KK_2..jpg


S2RE34_2..jpg -> T83_f2_2..jpg

S2RE34_3..jpg -> T83_f2_3..jpg


I tried to adopt to the script to find and replace but I am a newbie at scripting.


Mar 10, 2021 2:04 PM in response to SamSpring

The following regular expression revision will handle the following file formats and extract just the suffix part of the filename, just as the original script does, which is then used as a suffix for the replacement filename:

  • 101301844-01.jpg
    • $match[1] => -01.jpg
  • SD_WW_T83_3202_A0_SP21_EC_90.jpg
    • $match[1] => _90.jpg
  • All original filenames that have been working


replace the original regular expression pattern with this one. I recommend that you comment the original with a '#' sign in the first column.

# [[ $f =~ '^[A-Z0-9]+(_.*)$' ]] || continue

[[ $f =~ '^[A-Za-z0-9_]+([_-]+.*\..*)$' ]] || continue
mv "${f}" "${newfile}$match[1]"



Mar 9, 2021 2:28 AM in response to SamSpring

I can copy/paste the code that I previously posted directly into an Automator application's Run Shell Script action, and the application runs correctly, and without error dialogs, when passed the selected full folder path from the preceding Ask for Finder Items action. The same unmodified script runs in the Terminal by providing a direct or indirect path to the folder containing the images, and the data.csv file.


The code runs as intended for me on either macOS 11.2.2 or 11.2.3 update.


You should have the following as your Automator application contents, which you can right-click on and choose to open in a new Window for enlargement:


Mar 10, 2021 11:46 AM in response to VikingOSX

Thank you very much.


However, I need your help again.


We are getting pictures with difference format but we have to still change the first suffix and leave the rest the same.



We get different formats.


Test examples

oldfile -> newfile

101301844-01.jpg -> T84_3223_Z0-01.jpg

101301844-02.jpg -> T84_3223_Z0-02jpg


231301840-01.jpg -> T84_3244_Z0-01.jpg

231301840-02.jpg -> T84_3244_Z0-02.jpg


Another set be files formats:

SD_WW_T83_3202_A0_SP21_EC_90.jpg -> T85_3244_Z0_90.jpg

SD_WW_T83_3202_A0_SP21_EC_80.jpg -> T85_3244_Z0_80.jpg



Please can you show me how to adapt the script for any format we get?

I am happy to learn and pass my knowledge to others in our company.


Bulk renaming portion of files using automator workflow and csv file

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