BudiBadu Logo
Samplebadu

Bash by Example: Rename Files

Bash 5.0+

Batch renaming files using loops and parameter expansion to manipulate filenames, including changing extensions, adding prefixes or suffixes, and performing pattern-based transformations across multiple files simultaneously.

Code

#!/bin/bash

mkdir -p images
touch images/pic1.jpg images/pic2.jpg images/pic3.jpg

echo "Original:"
ls images

# Rename all .jpg to .png
for file in images/*.jpg; do
    # ${file%.jpg} strips the extension
    mv "$file" "${file%.jpg}.png"
done

echo -e "\nRenamed:"
ls images

# Add prefix
for file in images/*.png; do
    # $(basename "$file") gets filename without path
    filename=$(basename "$file")
    mv "$file" "images/new_$filename"
done

echo -e "\nPrefixed:"
ls images

rm -rf images

Explanation

Renaming multiple files at once is a common task in system administration and file management. While the mv command excels at renaming single files, batch operations typically require combining mv with loops and string manipulation techniques. Some Linux distributions include a rename utility (also known as prename), but this varies between Perl-based and util-linux versions, making pure Bash solutions more portable.

Bash provides powerful parameter expansion syntax for string manipulation:

  • ${var%pattern}: Remove shortest match from end (e.g., strip file extension)
  • ${var%%pattern}: Remove longest match from end
  • ${var#pattern}: Remove shortest match from beginning (e.g., strip prefix)
  • ${var##pattern}: Remove longest match from beginning
  • ${var/pattern/replacement}: Replace first occurrence
  • ${var//pattern/replacement}: Replace all occurrences

These expansions are processed directly by the shell without spawning external processes, making them extremely efficient for renaming operations. When combined with for loops that iterate over glob patterns, you can perform complex batch renaming tasks. The basename and dirname commands are also useful for extracting filename components when constructing new paths.

Code Breakdown

10
The for loop iterates over all files matching the glob images/*.jpg. Each file is processed individually.
12
${file%.jpg} is a parameter expansion that removes the shortest match of .jpg from the end. For images/pic1.jpg, this produces images/pic1, then we append .png.
19-22
A second loop adds prefixes. basename extracts just the filename without the directory path, allowing us to prepend new_.
21
Using command substitution $(basename "$file") captures the filename into a variable, which is then used to construct the new path.