Using the perl rename
utility:
$ rename -n 's/(\d+)(\.gro)$/sprintf "-%04i%s", $1, $2/e' ./*.gro
rename(./water-frames0.gro, ./water-frames-0000.gro)
rename(./water-frames116.gro, ./water-frames-0116.gro)
rename(./water-frames119.gro, ./water-frames-0119.gro)
rename(./water-frames135.gro, ./water-frames-0135.gro)
rename(./water-frames138.gro, ./water-frames-0138.gro)
rename(./water-frames154.gro, ./water-frames-0154.gro)
rename(./water-frames157.gro, ./water-frames-0157.gro)
This captures the digits before .gro as $1, and the .gro itself as $2, so they can be used in the replacement, the right-hand-side (RHS) of the s///
operator. The /e
modifier to the perl regular expression causes rename to evaluate the RHS as perl code. See man perlre
for details. The sprintf
starts with a literal -
and formats $1 and $2 as a 4-digit zero-padded integer (%04i
) and a string (%s
).
Note 1: perl rename is also known as file-rename
, perl-rename
, or prename
. Not to be confused with the rename
utility from util-linux
which has completely different and incompatible capabilities and command-line options.
Note 2: the -n
option makes it a dry run, so it will only show what it would do without actually renaming any files. Remove the -n
, or replace it with -v
for verbose output, when you've confirmed that it does what you want.
Note 3: perl rename can take filenames as arguments from the command line or from stdin (as either newline or NUL separated filenames). rename's -0
option pairs well with input piped from find ... -print0
. It also works well with find ... -exec rename ... {} +
.