Renaming a Batch of Files with Bash

The following is a bash script which renames a bunch of files. To recreate this script:

  • Use Linux.

  • Open a text editor.

  • Copy-paste the code below.

  • Save the file (maybe even use the extension .sh like you are supposed to do).

  • Change the file properties to an executable (chmod +x filename).

I use this script often when moving a bunch of images to a website (these images are usually taken with different devices resulting in a bunch of disorganized names).

Anyway, here is the code:

#!/bin/bash

# This script renames a bunch of files in a directory and gives them
# a new name based on a new base name and the modified date and time.

# Wherever this script resides, it needs two sub-directories:
# images-original (the place where the original files are located).
# images-renamed (the place where they are copied to with new names).

IN='images-original' 
OUT='images-renamed'

# Get the new name. If one is provided, a hyphen is added.

read -p 'Enter a new name: ' NAME
if [ "$NAME" != "" ]; then
NAME+="-"
fi

previous=''
x=0

# Sending the following to a text file allows iteration by line breaks.
# Otherwise, stuffing the follow into a memory variable always results
# in list separation by spaces. A problem if file names have spaces.

ls -tr $IN > list.txt

while read item;
do

# The following strips out the name and extension, replaces spaces with
# underscores, makes everything lower case... just in case I need it later.

f=${item##*/}
N=${f%.*}
n=${N// /_}
E=${f##*.}
e=${E,,}

# This one gets the modified date and time of the file.

d=$(date -r "$IN/$item" +%Y%m%d-%H%M%S)

# Bash `if` notes:
# Space around `[` and `]` so that they do not become part of the variable.
# Provide double (evaluate the inside) quotes around strings. This allows
# expansion of the variable and then evaluates it (single quotes would not).
# And, if the variable has spaces or is empty, it remains a single string.

# This checks to see if the modified date and time is exactly the same as
# the previous file. This usually happens when files are copied without
# preserving the original information (you forgot the archive option -a).

if [ "$NAME$d" == "$previous" ]; then
x=$((x+1))
else
x=0
previous=$NAME$d
fi

cp -p "$IN/$item" $OUT/$NAME$d-$x.$e
echo "$item" $OUT/$NAME$d-$x.$e

done < list.txt

I hope this helps ya!




Copyright, provided by, and under the protection of Worktable CNC, LLC.
Details and Terms of Use may be found here: worktablecnc.us/legal