BASH

Batch Rename Files with Sequential Numbering

Effortlessly rename multiple files in a directory, adding sequential numbers and maintaining file extensions, ideal for managing image assets or documents.

#!/bin/bash

# This script renames files in the current directory with a common prefix
# and sequential numbering, preserving their original extensions.

# Usage: ./rename_files.sh "image" "jpg"
# Example: file1.jpg -> image-001.jpg, file2.jpg -> image-002.jpg

if [ "$#" -lt 1 ]; then
    echo "Usage: $0 <new_prefix> [extension_filter] [starting_number]"
    echo "  <new_prefix>: The new prefix for the filenames (e.g., 'photo')"
    echo "  [extension_filter]: Optional. Only rename files with this extension (e.g., 'jpg'). If empty, renames all."
    echo "  [starting_number]: Optional. The number to start counting from (default: 1)."
    exit 1
fi

NEW_PREFIX="$1"
EXTENSION_FILTER="${2:-}" # Default to empty string (no filter)
START_NUM="${3:-1}"       # Default starting number to 1

COUNTER=$START_NUM

# Use an array to store files to avoid issues with spaces in filenames
if [ -n "$EXTENSION_FILTER" ]; then
    # Filter by extension
    FILES_TO_RENAME=(*."$EXTENSION_FILTER")
else
    # No filter, rename all files
    FILES_TO_RENAME=(*)
fi

# Remove script itself from list if present and not intended for renaming
for i in "${!FILES_TO_RENAME[@]}"; do
    if [[ "${FILES_TO_RENAME[$i]}" == "$(basename "$0")" ]]; then
        unset 'FILES_TO_RENAME[i]'
    fi
}

echo "Preparing to rename files with prefix: '$NEW_PREFIX' (starting from $START_NUM)"
if [ -n "$EXTENSION_FILTER" ]; then
    echo "Filtering by extension: '$EXTENSION_FILTER'"
fi
echo "---"

for OLD_FILE in "${FILES_TO_RENAME[@]}"; do
    if [ -f "$OLD_FILE" ]; then
        # Extract extension
        EXTENSION="${OLD_FILE##*.}"
        FILENAME="${OLD_FILE%.*}"
        
        # Pad the counter with leading zeros (e.g., 001, 010, 100)
        # Use printf to format number with leading zeros (e.g., %03d for 3 digits)
        PADDED_NUM=$(printf "%03d" "$COUNTER")
        
        # Construct new filename
        if [ "$EXTENSION" != "$FILENAME" ]; then # Check if there was an extension
            NEW_FILE="${NEW_PREFIX}-${PADDED_NUM}.${EXTENSION}"
        else
            NEW_FILE="${NEW_PREFIX}-${PADDED_NUM}" # No extension, just prefix-num
        fi
        
        # Avoid overwriting existing files
        if [ -e "$NEW_FILE" ]; then
            echo "Warning: '$NEW_FILE' already exists. Skipping '$OLD_FILE'."
        else
            mv "$OLD_FILE" "$NEW_FILE"
            echo "Renamed '$OLD_FILE' to '$NEW_FILE'"
        fi
        
        COUNTER=$((COUNTER + 1))
    fi
done

echo "---"
echo "Batch rename complete."
How it works: This bash script provides a flexible way to batch-rename files within a directory. It takes a new prefix, an optional extension filter, and an optional starting number as arguments. For each matched file, it constructs a new filename using the provided prefix, a sequentially increasing padded number (e.g., `001`, `002`), and preserves the original file extension. This is highly useful for organizing image assets, documents, or any collection of files that need consistent naming.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs