I have a batch of files:

$ ls
Li1Fe1O2_11 Li1Fe2O3_8  Li1Fe3O4_2  Li1Fe3O4_5  Li2Fe1O3_16 Li2Fe2O4_12 Li3Fe1O4_19 Li3Fe1O4_22
Li1Fe1O2_14 Li1Fe2O3_9  Li1Fe3O4_3  Li1Fe3O4_6  Li2Fe1O3_17 Li2Fe2O4_13 Li3Fe1O4_20
Li1Fe2O3_7  Li1Fe3O4_1  Li1Fe3O4_4  Li2Fe1O3_15 Li2Fe2O4_10 Li3Fe1O4_18 Li3Fe1O4_21

And I would like to rename them into:


I tried to look into rename without success.

  • 3
    How is the numbering of the final files connected to the original filenames? Are they just numbered serially? – jofel Aug 25 '15 at 17:31

Use this:

for f in *; do
  mv -v "$f" "enum-$(printf '%0*d' 5 $c)"

The c=<your_starting_number>; I assumed 132 as in your question. Then the for loop runs trough all the files in the current directory. For every file the mv command is called. the printf utility prints the new filename with leading zeros. And finally the counter variable $c increments +1.

Edit: If you want only directories use this (*/ machtes only directories, the rest stays the same):

for d in */ ; do
  mv -v "$d" "enum-$(printf '%0*d' 5 $c)"
  • That's fantastic!!!! – user40780 Aug 25 '15 at 17:58
  • one subtle question... So some of those are directories, however, if I want to change only the filenames of directory. What should I do ? Thank you. – user40780 Aug 25 '15 at 18:06
  • @user40780 See my edit – chaos Aug 25 '15 at 18:08
  • 1
    c=$((c=c+1)) is unnecessary. All you need is c=$((c+1)). In fact you can even just do ((c++)). – Digital Trauma Aug 25 '15 at 18:12
  • @DigitalTrauma As specified in POSIX (pubs.opengroup.org/onlinepubs/9699919799/utilities/…) this ($((c=c+1))) has the best portability – chaos Aug 25 '15 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.