Rename files in sub directories with sequential numbers

I can rename a file with sequential numbers from 1 to N with this script:

num=1
for file in *.dat;do
       mv "$file" "$(printf "%u" $num).txt"
       let num=num+1
done

The script begins with renaming a some.dat file to 1.dat.txt and goes on sequentially renaming other DAT files to 2.dat.txt, 3.dat.txt and so on.

This script works very well on my Linux system when I have one directory with all DAT files in it. But it cannot work when I have a parent directory with sub directories. My directory structure is like this:

Parent Directory and inside parent directory there are 20 more sub directories and inside those sub directories are the DAT files.

Is there any way I can modify the above script so that (I am in my parent directory and run this script) it takes in one sub-directory and renames all the files in that directory in sequential numbers say 1 to N, then goes to another sub-directory and renames from N+1 to M, then goes to third sub-directory and renames from M+1 to X and so on?

The auto-increment operator and the -v option of mv are not standard, so use zsh, ksh93 or bash to run the script.
I'm assuming there are no embedded newlines in the filenames.

c=0
find . -type f -name '*.dat' |
  while IFS= read -r; do
    mv -v -- "$REPLY" "${REPLY%/*}/$(( ++c )).dat"
  done

If you want standard code, you should use something like this:

$(( c = c + 1 ))

... and you should remove the -v option from the mv command.

P.S. I don't remember if read without varname is standard, to lazy to check it right now :slight_smile:

1 Like