how to copy and rename file with for loop in bash script?

Learn how to copy and rename file with for loop in bash script? with practical examples, diagrams, and best practices. Covers linux, bash, shell development techniques with visual explanations.

Copy and Rename Files with a Bash for Loop

A stylized illustration of files being copied and renamed, with a loop symbol indicating automation.

Learn how to efficiently copy and rename multiple files using a for loop in Bash scripts, covering various renaming strategies and best practices.

Automating file operations is a common task in shell scripting. When you need to copy a set of files and apply a new naming convention to each copied file, a for loop in Bash is an incredibly powerful and flexible tool. This article will guide you through the process, demonstrating how to construct effective loops for various renaming scenarios, from simple prefixes to more complex pattern-based transformations.

Basic File Copy and Rename with a for Loop

The fundamental approach involves iterating over a list of source files, and for each file, constructing a new destination filename before executing the cp command. This method is versatile and can be adapted to many different renaming patterns. We'll start with a simple example: adding a prefix to copied files.

#!/bin/bash

SOURCE_DIR="./original_files"
DEST_DIR="./renamed_copies"
PREFIX="new_"

mkdir -p "$DEST_DIR"

for file in "$SOURCE_DIR"/*; do
  if [ -f "$file" ]; then
    filename=$(basename "$file")
    cp "$file" "$DEST_DIR/${PREFIX}${filename}"
    echo "Copied '$file' to '$DEST_DIR/${PREFIX}${filename}'"
  fi
done

Basic for loop to copy files and add a prefix to their names.

Advanced Renaming Strategies

Beyond simple prefixes, Bash offers powerful string manipulation capabilities that can be used within a for loop to achieve more complex renaming. This includes replacing parts of a filename, adding suffixes, or even using regular expressions for pattern matching and substitution. Let's explore some common scenarios.

flowchart TD
    A[Start Loop: Iterate over files] --> B{Is it a regular file?}
    B -- Yes --> C[Extract original filename]
    C --> D[Construct new filename (e.g., add prefix, replace string)]
    D --> E[Execute `cp` command: original_file -> new_file]
    E --> F[Log action]
    F --> G{More files?}
    G -- Yes --> A
    G -- No --> H[End]

Flowchart illustrating the process of copying and renaming files within a for loop.

Renaming by Replacing Substrings

A common requirement is to replace a specific string within the filename. Bash parameter expansion allows for powerful substring replacement directly within the loop. This is particularly useful for versioning, changing file types, or standardizing names.

#!/bin/bash

SOURCE_DIR="./reports"
DEST_DIR="./archive_reports"
OLD_STRING="_draft"
NEW_STRING="_final"

mkdir -p "$DEST_DIR"

for file in "$SOURCE_DIR"/*"$OLD_STRING"*; do
  if [ -f "$file" ]; then
    filename=$(basename "$file")
    new_filename="${filename//$OLD_STRING/$NEW_STRING}"
    cp "$file" "$DEST_DIR/${new_filename}"
    echo "Copied '$file' to '$DEST_DIR/${new_filename}'"
  fi
done

Copying files and replacing a substring in their names.

Adding a Timestamp or Sequence Number

For backup or versioning purposes, you might want to add a timestamp or a sequential number to the copied files. This can be achieved by incorporating the date command or a counter variable into your loop.

#!/bin/bash

SOURCE_DIR="./logs"
DEST_DIR="./daily_backups"

mkdir -p "$DEST_DIR"

TIMESTAMP=$(date +%Y%m%d_%H%M%S)

for file in "$SOURCE_DIR"/*.log; do
  if [ -f "$file" ]; then
    filename=$(basename "$file")
    # Remove .log extension, add timestamp, then re-add .log
    base_name="${filename%.log}"
    cp "$file" "$DEST_DIR/${base_name}_${TIMESTAMP}.log"
    echo "Copied '$file' to '$DEST_DIR/${base_name}_${TIMESTAMP}.log'"
  fi
done

Copying log files and appending a timestamp to their names.

1. Define Source and Destination

Clearly define SOURCE_DIR and DEST_DIR variables at the beginning of your script. This makes the script easier to read and modify.

2. Create Destination Directory

Use mkdir -p "$DEST_DIR" to ensure the destination directory exists. The -p flag prevents errors if the directory already exists.

3. Iterate Safely

Use for file in "$SOURCE_DIR"/*; do to iterate over files. Always check if [ -f "$file" ] to ensure you are processing regular files and not directories or other special file types.

4. Extract Filename

Use filename=$(basename "$file") to get just the filename without the path. This is crucial for constructing the new name correctly.

5. Construct New Filename

Apply Bash parameter expansion (e.g., ${filename//OLD/NEW}, ${filename%.ext}, ${filename%/*}) to manipulate the filename as needed. Be precise with your patterns.

6. Execute Copy Command

Use cp "$file" "$DEST_DIR/${new_filename}" to perform the copy operation. Double-check the source and destination paths.

7. Add Logging

Include echo statements to provide feedback on which files are being processed and what their new names are. This is invaluable for debugging and monitoring.