Reputation: 4014
I have a catalogue structure like this:
AD
-> AD01
-> DSC123.jpg
-> DSC124.jpg
-> AD02
-> DSC234.jpg
-> DSC1455.jpg
-> AD03
->...
-> AD04
->...
->...
AE
->...
...
No I would like to run a script that will traverse whole tree and rename each folder files to be a consecutive numbers 01.jpg, 02.jpg... etc.
I found something like this to help with consecutive numbers:
find -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv %s %02d.jpg\n", $0, a++ }' | bash
but how do I make it run on all the folders recursively, throughout the tree (there are like 1000 of folders each with about 6-20 files).
Edit: Result should look like this:
AD
-> AD01
-> 01.jpg
-> 02.jpg
-> AD02
-> 01.jpg
-> 02.jpg
-> AD03
->...
-> AD04
->...
->...
AE
->...
...
Upvotes: 0
Views: 1055
Reputation: 185161
The shortest one using perl :
cd AD/AD02
rename -n 'no strict; s@.*(?=\.)@sprintf "%0.2d", ++$x@e' *.jpg
Remove -n
switch when the output looks good.
There are other tools with the same name which may or may not be able to do this, so be careful.
The rename command that is part of the util-linux
package, won't.
If you run the following command (GNU
)
$ file "$(readlink -f "$(type -p rename)")"
and you have a result that contains Perl script, ASCII text executable
and not containing ELF
, then this seems to be the right tool =)
If not, to make it the default (usually already the case) on Debian
and derivative like Ubuntu
:
$ sudo apt install rename
$ sudo update-alternatives --set rename /usr/bin/file-rename
If you don't have this command with another distro, search your package manager to install it or do it manually (no deps...)
This tool was originally written by Larry Wall, the Perl's dad.
Upvotes: 1
Reputation: 14949
You can try this bash
script,
#!/bin/bash
for dir in $(find -type d \( ! -name '.*' \))
do
i=1;
for file in $(find "$dir" -name '*.png')
do
a=$(printf "%02d" $i)
new=${file%/*}
echo "mv $file $new/$a.png"
let i=i+1
done
done
It will list out the mv
commands that is going to apply. See whether it is giving what you expected. Finally, replace the echo
with mv
command.
Upvotes: 0
Reputation: 11
Use find to find the directories then cd into each directory in turn and rename the files.
find /path/to/catalogue -type d -exec bash -c '
shopt -s nullglob
for dir in "$@" ; do
( cd "$dir" || exit
files=( *[!0-9]*.jpg )
for (( n = 0 ; n < "${#files[@]}" ; n++ )) ; do
printf -v target '%02d.jpg' $(( n + 1 ))
mv -- "${files[$n]}" "$target"
done )
done
' bash {} +
Upvotes: 1
Reputation: 25885
#!/bin/bash
files=$(find . -name "*.jpg" -type f)
a=1
for i in $files; do
dir=$(dirname "$i")
new=$(printf "%04d" ${a})
mv ${i} $dir/${new}.jpg
let a=a+1
done
Upvotes: 0