shell-script – Rename Files Based on Directory Names

filesjpegrenameshell-script

How can I rename .jpg files in multiple folders based on the name of the folder? I also want the .jpg files to remain in their respective folders and not moved. The folder names have no spaces.

So, for example, if the folder name is Red, then I want the resulting file names to be:

Red000001.jpg
Red000002.jpg
Red000003.jpg

I have the following command, but it gives undesirable results, moving renamed files outside of their respective folders and making the file names "sloppy":

start=$PWD;
for directory in *; do
  cd "$directory";
  for filename in *; do
    mv "$filename" ../"Folder $directory - $filename";
  done;
  cd "$start";
done

Best Answer

If you have to cd in and out of several directories then it makes sense to use cd - instead which takes you to the last current working directory. Or you use pushd / popd (in bash).

for directory in *; do
  pushd "$directory"
  index=1
  for filename in *; do
    extension="${filename##*.}"
    if [ "$filename" != "$extension" ]; then
      extension=".$extension"
    else
      # i.e. there is no dot in the file name
      extension=""
    fi
    target_filename="${directory}$(printf "%06d" "$index")${extension}"
    if [ -f "$target_filename" ]; then
      echo "File ${target_filename} exists; aborting."
      exit 3
    fi
    mv "$filename" "${target_filename}"
    ((index++))
  done
  popd
done

This code does not handle name collisions (if there is already a file Red00004) well. It just checks and aborts.

Related Question