Search code examples
csvcommand-line-interfacefile-renamebatch-rename

Batch rename in Terminal by appending prefix from .csv file


Edit (to improve question):

Screenshot

In the image above you can see the naming of a series of files.

Each file has a filename of: 01-NameOfProject_Data Set X-01.png where X is sequential from 1 to 24 (please note! NOT 01, 02, ..., 24)

I have created two .csv files (to explore which works better upon your answer) as shown in the picture.

First step: I need to add the country-code prefix to each corresponding file. E.g. EN_01-NameOfProject_Data Set 1-01.png

Second step: I need to remove the part _Data Set X-01 The result would be EN_01-NameOfProject.png

I am kindly asking for help in the above two steps so I can better understand the procedure. I need to do this via macOS Terminal. I have install rename via Homebrew with brew install rename

Original question: I have a list of files that look like this:

01-NameOfProject_Data Set 1-01.png
01-NameOfProject_Data Set 2-01.png
01-NameOfProject_Data Set 3-01.png
...
01-NameOfProject_Data Set 24-01.png

I also have an Excel file (which I can save as .csv). It has a single column and exactly as many rows as the amount of the aforementioned files. Each cell has a language shortcode. It looks like this:

EN
GR
IT
...
BU

The Excel file in the correct (corresponding) order as the files meaning that: 01-NameOfProject_Data Set 1-01.png is indeed in English (EN) and so on.

How would you batch rename the files so you'd end up with something like:

EN_01-NameOfProject_new-text.png
GR_01-NameOfProject_new-text.png
IT_01-NameOfProject_new-text.png
...
BU_01-NameOfProject_new-text.png

Solution

  • Like this, using Perl's rename:

    brew install rename
    

    Remove -n switch, aka dry-run when your attempts are satisfactory to rename for real.

    #!/usr/bin/env bash
    
    c=0 arr=( * )
    while IFS=, read -r _ country; do
        rename -n "s/^(\d+).*/${country}_${1}NameOfProject_new-text.png/" "${arr[c++]}"
    done < /tmp/file.csv
    

    Output

    rename(01-NameOfProject_Data Set 1-01.png, EN_NameOfProject_new-text.png)
    rename(01-NameOfProject_Data Set 2-01.png, GR_NameOfProject_new-text.png)
    rename(01-NameOfProject_Data Set 24-01.png, IT_NameOfProject_new-text.png)
    rename(01-NameOfProject_Data Set 3-01.png, BU_NameOfProject_new-text.png)
    

    If order is not natural, then use:

    #!/usr/bin/env bash
    
    readarray -td '' files < <(
        ls --zero -v -- *.png
    )
    c=0
    while IFS=, read -r _ country; do
        rename -0 -n "s/^(\d+).*/${country}_${1}NameOfProject_new-text.png/" "${files[c++]}"
    done < /tmp/file.csv
    

    Output

    rename(01-NameOfProject_Data Set 1-01.png, EN_NameOfProject_new-text.png)
    rename(01-NameOfProject_Data Set 2-01.png, GR_NameOfProject_new-text.png)
    rename(01-NameOfProject_Data Set 3-01.png, IT_NameOfProject_new-text.png)
    rename(01-NameOfProject_Data Set 24-01.png, BU_NameOfProject_new-text.png)