Problem: I had a few thousand files in a directory and needed them to be in a series of numbered folders – specifically with leading zeros – with no more than 100 files in each. Don’t ask why… just some weird old batch program that needs files presented that way. Obviously manually creating directories and moving the files was going to take a while. Also, this needed to be done via a cron job, so I needed something scriptable.
Solution: Thankfully all sorts of magic can be done on the *nix command line, and we have access to very useful formatting functions like printf
and for
loops.
The following command achieves what I needed:
i=0; for f in *; do d=dirname_$(printf %03d $((i/100+1))); mkdir -p $d; mv "$f" $d; let i++; done
Notice that it’s actually a series of commands separated by semicolons. Easier to use it with an alias in this form, but to understand it fully you might want to read it command by command.
Note also that the leading zeros in the directory names are achieved by applying a format with the printf
function. The %03d
bit means format as a 3-digit number with leading zeros. More info on the formats here: printf manual
Testing the solution: To test this, create some dummy files. The following command will create 500 files named 001-file.txt
through to 500-file.txt
:
$ touch {001..500}-file.txt
…then run the commands to move the created files into new named and numbered directories:
$ i=0; for f in *; do d=dirname_$(printf %03d $((i/100+1))); mkdir -p $d; mv "$f" $d; let i++; done
The result should be 5 directories, each named dirname_001
, dirname_002
etc etc, and each with 100 files in, equally split.
My example results are shown in the screenshot below:
Please let me know if this helped you at all. Or if it’s wrong or could be improved, please comment and I’ll update the post with your suggestions.