I have a directory with sub-directories that contains images.I want to make a new directory and move all the images in there and then sort them to sub-directories with the order year/month/day of modification.

I thought of using find and mv to move all the images to the new directory, find the date of first image in directory, make a sub-directory named after the year of this image and then find and move all the images with the same year in that sub-directory.I will do this for every image in the main directory and then I will repeat the procedure in every sub-directory for month and then day.

My problem is that I believe that there must be a sorter way for me to do this.

Any ideas?


With zsh:

zmodload zsh/files # bring in builtin versions of mkdir and mv to speed things up
zmodload zsh/stat

for file (**/*.jpg(N.)) {
   zstat -F %Y/%m/%d -A date +mtime -- $file &&
     mkdir -p $date &&
     mv -- $file $date

If you don't have zsh and can't install it, with GNU tools, you could minimize the number of commands run with:

(export LC_ALL=C
  find . -name '*.jpg' -type f -printf '%TY/%Tm/%Td\0%p\0' |
    gawk -v 'RS=\0' -v q="'" '
      function shquote(s) {
        gsub(q, q "\\" q q, s)
        return q s q
        date = $0; getline file
        dir[date] = dir[date] " " shquote(file)
      END {
        printf "mkdir -p ."
        for (d in dir) printf " %s", d
        print " || exit"
        for (d in dir) print "mv" dir[d], d
      }' | sh

(you may want to remove the | sh at first to check that it does what you want).

Note that neither of those will guard against conflicts. For instance, if you have a a/foo.jpg and b/foo.jpg both last modified on 2017-11-01, they will both be moved to 2017/11/01/foo.jpg, one of them overwriting the other. You may want to add the -i flag to mv to guard against it.

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.