How would I recursively rename
Bluebellgray 19707 Rug P1.jpg
Bluebellgray Amal 1972407 Rug R1.jpg
Bluebellgray Random 1907 Rug R2.jpg
Words Amal 1707 Rug R3.jpg
Whatever 9707 Rug R4.jpgto
P1.jpg
R1.jpg
R2.jpg
R3.jpg
R4.jpgI'm only interested in the last 6 characters.
I assume the answer begins with rename -n and then some funky regular expression? To get it recursive would I need to pipe and rename? I'm also only interested in .jpg files.
Thanks
1 Answer
In the following, remove the -n once you are happy about the proposed transformations.
With rename:
rename -n 's/.*(..)\.jpg$/$ *.jpgTo make it recurse into subdirectories, you have two options:
use a recursive shell glob
shopt -s globstar rename --nopath -n 's/.*(..)\.jpg$/$ **/*.jpguse
findfind . -name '*.jpg' -execdir rename --nopath -n 's/.*(..)\.jpg$/$ {} +
Note the addition of the --nopath option to prevent the rename command from removing the leading path elements. An alternative would be to change the leading .* of the regular expression pattern to [^/]*. Note also that the globstar version will fail if the number of matches is too large (or, more precisely, if the combined argument length exceeds ARG_MAX).
With mmv:
mmv -n '*??.jpg' '#2#3.jpg'This one is tricky to make recursive since it does its own pattern matching. It could be wrapped in a find -type d -execdir ... command I suppose.
Here, remove the echo once you are happy about the proposed transformations.
With a simple shell loop, assuming we may remove everything up to and including the last space character:
for f in *.jpg; do echo mv -n -- "$f" "${f##* }"; doneYou can make this recurse using find in the same way as for the rename command:
find . -name '*.jpg' -execdir sh -c 'for f; do echo mv -n -- "$f" "${f##* }"; done' sh {} +Note that if you want to use the mv "$f" "${f: -6}" version suggested in Raffa's comment you would need to use one of the shells that supports negative substring indexing such as bash/ksh/zsh for the sh -c scriptlet.
You could use a recursive glob with the shell loop, but you'd need to separate the dirname and basename in order to apply the parameter substitution ex.
for f in ./**/*.jpg; do d="${f%/*}"; b="${f##*/}"; echo mv "$f" "$d/${b: -6}"; done 11