linuxbashrenamebatch-rename

Avoiding file renaming duplication in Linux bash script when rerun


I have 100 directories from data001 to data100 in my Linux system, and I want my bash script to rename all the data files with different extensions according to their directory names. For example, files in directory data001should be renamed as *001.txt and *001.nc and files in data002 should be renamed as *002.txt and *002.nc and so on. I have the bash script that does the job, but when I try to rerun the script, it duplicates the name, for example, data001 - *001001.txt *001_001.nc. I want to make sure that if I rerun the script it the code doesn't affect the naming format.

#!/bin/bash
for ((ii=1; ii<=100; ii++))
do
    dirname=$(printf "data%03d" $ii)
    for file in $dirname/*
    do
        filename=$(basename "$file")
        extension="${filename##*.}"
        filename_without_ext="${filename%.*}"
        newname=$(printf "%s_%03d.%s" "$filename_without_ext" $ii "$extension")
        
        # Skip if the file is already in the desired format
        if [[ "$filename_without_ext" != *"_${ii}" ]]; then
            mv "$file" "$dirname/$newname"
        fi
    done
done

Solution

  • The string interpolation of *"_${ii}" doesn't produce the suffix the way you expect it.

    > ii=3
    > echo "_${ii}"
    _3
    

    but I suppose you expect _003 for the format comparison.

    I suggest you prepare the suffix in the expected format beforehand and then use it throughout the script.

    #!/bin/bash
    for ((ii=1; ii<=100; ii++))
    do
        dirname=$(printf "data%03d" $ii)
        for file in $dirname/*
        do
            filename=$(basename "$file")
            extension="${filename##*.}"
            filename_without_ext="${filename%.*}"
            suffix=$(printf "_%03d" $ii)
            newname=$(printf "%s%s.%s" "$filename_without_ext" "$suffix" "$extension")
    
            # Skip if the file is already in the desired format
            if [[ "$filename_without_ext" != *"$suffix" ]]; then
                mv "$file" "$dirname/$newname"
            fi
        done
    done