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!