Move characters from the start of filenames to the end (before extension) and add whitespace
I have ~2000 files in an original naming scheme.
I need to take them all, move the first 4 characters to the end of the filename before the extension, and then add a whitespace before the first 4 characters.
Basically, from:
0123 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).jpg
to
[UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL) 0123.jpg
Solution 1:
This should work:
rename -n 's/^([0-9]+) (.*)\.jpg/$2 $1.jpg/' /path/to/files/*.jpg
Sample:
0324 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).txt
0123 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).txt
0124 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).txt
Results:
rename(0123 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).txt, [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL) 0123.txt)
rename(0124 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).txt, [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL) 0124.txt)
rename(0324 [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL).txt, [UNKNOWN] (Final Fantasy 9) headshot of Freya Crescent {sketch} (ORIGINAL) 0324.txt)
Note: Tested with .txt
files will also work on jpg filenames
Information:
([0-9]+)
: pick the numbers at the front.
(.*)
: pick every other thing till the file extension.
$2 $1.txt
: return the captured groups with the returned group for numbers
placed close to the file extension jpg
and add a space before the numbers.
-n
: run without changing filename so we see what files are changed and what the names are changed to, remove this to rename the files.
Solution 2:
Use find
and Shell Parameter Expansion
:
- If you don't have
rename
installed (but most probably it's already installed as part of Perl packages). - You can perform on all or specified matched file patterns "*.jpg" only.
- It's recursively as
find
nature is.
find . -type f -execdir \
sh -c 'X="[${1#*[}"; Y="${1%% *}";
echo mv -v "$1" "${X%.*} ${Y#./}.${X##*.}"' find-sh '{}' \;
Explanations:
X="[${1#*[}"
(cut-up-to-first-prefix): This removes everything until first[
seen, and appends[
back to the pattern.Y="${1%% *}"
(cut-up-to-last-suffix): This removes everything until last space seen starts from end to the beginning of the filename; This will result./PATTERN
which is./0123
as example.${X%.*}
(cut-up-to-first-suffix): This removes suffix (ex:.jpg
).Y="${Y#./}"
(cut-up-to-first-prefix): This removes./
from variableY
and will result PATTERN only from second step which is0123
now..${X##*.}"
(cut-up-to-last-prefix): This removes everything until last dot.
seen starts from beginning to the end of the filename and append back a dot.
; This will result.PATTERN
which is.jpg
now.-execdir
used here to don't result file path byfind
command and it's safe to intact the /path/to/files/. This will produce a prompt if you have current directory in your PATH or if it contains relative paths which is unsafe.echo
is used for dry run, remove it to have actual rename.