I have a lot of files that are named like:
data1_1.txt
data1_2.txt
data1_3.txt
data2_1.txt
data2_2.txt
...
However these were downloaded and named in the reverse ordering. How could I rename all of these in a batch so that the result would be:
data1_3.txt
data1_2.txt
data1_1.txt
data2_2.txt
data2_1.txt
...
My first thought was just a bash / zsh script but if there's another tool that would work better please let me know.
Best Answer
With
zsh
:(remove the
-n
(dry-run) and:
, if happy (and remember to re-initializec=()
before running again without dry run)).<->
: is like<1-12>
to match decimal numbers in a range, but here with no bound specified, so matches any sequence of one or more decimal digits. Could also be written[0-9]##
where##
iszsh
's equivalent of ERE+
.(#q...)
is the explicit syntax for specifying glob qualifiers.n
: sorts numericallyOn
: sorts by name in reverse. So withn
above, that sorts the list of matching files numerically in reverse.$1
contains what's captured in(*)
, so the part before_<digits>.txt
.$((++c[${(b)1}]))
, where$c
is the associative array declared earlier.${(b)1}
is$1
with glob characters escaped (without it, it wouldn't work properly if$1
contained]
).-renamed
suffix which is stripped in the second stage), to avoid overwriting files in the process.On your sample, that gives:
Note that technically, it doesn't reverse the order, or only does it in the case where the numbers are incrementing by one and start at 1 like in your sample. It will turn all of
[1, 2, 3]
,[4, 5, 6]
,[0, 10, 20]
to[3, 2, 1]
.To reverse the list, it would be a bit more involved. It could be something like:
(remove
echo
when happy).And run the
zmv '(*)-renamed' '$1'
again as the second phase.On a different sample with a additional
[0, 3, 10, 20]
list as a third example, that gives:Those solutions make no assumption on what character (or non-character) the file names may contain, won't rename files unless they end in
_<digits>.txt
. Thezmv
-based approach will guard against overwriting files named with a-renamed
suffix that would have been there beforehand, not the latter approach (though-i
will causemv
to prompt you before that happens). Alternatively, instead of adding a-renamed
suffix, you could move the renamed file into arenamed
directory.