Adrian Adrian - 12 days ago 5
Linux Question

Batch rename images to folder name + sequential number

I want to rename files in a directory with subdirectories to parent it's directory name + sequential numbers.

For example:

hello-images/
├── first-black
│   ├── full_b200056_m.png
│   ├── full_b200056_x_DSC01973.JPG
│   ├── full_b200056_x_DSC01978.JPG
│   ├── full_b200056_x_DSC01988.JPG
│   ├── full_b200056_x_DSC01994.JPG
│   ├── full_b200056_x_DSC02003.JPG
├── second-atlas
│   ├── full_b200035_m1.png
│   ├── full_b200035_x_3926.JPG
│   ├── full_b200035_x_3928.JPG
│   ├── full_b200035_x_3931.JPG
│   ├── full_b200035_x_3944.JPG


Desidered result:

hello-images/
├── first-black
│   ├── first-black_1.png
│   ├── first-black_2.JPG
│   ├── first-black_3.JPG
│   ├── first-black_4.JPG
│   ├── first-black_5.JPG
│   ├── first-black_6.JPG
├── second-atlas
│   ├── second-atlas_1.png
│   ├── second-atlas_2.JPG
│   ├── second-atlas_3.JPG
│   ├── second-atlas_4.JPG
│   ├── second-atlas_5.JPG

Answer

From hello-images directory, do:

for d in */; do i=1; for f in "$d"/*.*; do echo mv -- "$f" "$d${d%/}_${i}.${f##*.}"; ((i++)); done; done

This is dry-run, it will show the mv commands to be run. If satisfied with the changes to be made, remove echo for actual action:

for d in */; do i=1; for f in "$d"/*.*; do mv -- "$f" "$d${d%/}_${i}.${f##*.}"; ((i++)); done; done

Expanded form:

for d in */; do 
    i=1
    for f in "$d"/*.*; do 
        mv -- "$f" "$d${d%/}_${i}.${f##*.}"
        ((i++))
    done
done