Ubuntu: Change directory structure from /YEAR/MONTH/DAY/ to /YEAR-MONTH-DAY


I need to change my directory structure for my photos from /YEAR/MONTH/DAY/ to /YEAR-MONTH-DAY

I know this can sort of be done with exiftool, but it will only work on files containing EXIF-tags, and I have xmp-sidecar files corresponding to each image, and these need come along too. So I recon script of some kind would be the best way.

I sat down and tried to learn RegEx, sed, bash and what not, and given enough time, I guess I should be able to figure this one out, but right now I am in a hurry, so any help would be appreciated.



The rename utility in Ubuntu can rename directory structures but it won't clean up after itself.

rename 's#(.+)/(.+)/(.+)#$1-$2-$3#' */*/*/  

Stick -vn on the end if you just want it to tell you what it's going to do before it renames anything, but here's a little test harness that shows you what's possible:

$ mkdir -p 2014/06/15  $ touch 2014/06/15/photo_{001..003}.jpg  $ tree  .  â""â"€â"€ 2014      â""â"€â"€ 06          â""â"€â"€ 15              â"œâ"€â"€ photo_001.jpg              â"œâ"€â"€ photo_002.jpg              â""â"€â"€ photo_003.jpg    $ rename 's#(.+)/(.+)/(.+)#$1-$2-$3#' */*/*/  $ tree  .  â"œâ"€â"€ 2014  â"‚   â""â"€â"€ 06  â""â"€â"€ 2014-06-15      â"œâ"€â"€ photo_001.jpg      â"œâ"€â"€ photo_002.jpg      â""â"€â"€ photo_003.jpg  

Simply put it's being fed the third-level directories and renaming is reading the earlier two segments and renaming it, sticking it in the current directory. As you can see there will be a load of year directories. Assuming they're empty you could clean up with something like (and I pray you check they're empty first):

find -maxdepth 1 -type d -regex '\./[0-9][0-9][0-9][0-9]' -exec rm -irf "{}" \;  

I'm using the -i option to force it to ask you before deleting every file. Remove that at your own risk.


cd base  # the trailing slash in the pattern limits the results to directories, not files  for subdir in */*/*/; do      # $subdir is now "year/mon/day/"      subdir=${subdir%/}        # remove the trailing slash      newdir=${subdir//\//-}    # replace all slashes with hyphens      mkdir "$newdir"      mv "$subdir"/* "$newdir"  done  


Try this:

    TOP=$PWD  for y in *; do    if cd $y; then      for m in *; do        if cd $m; then             for d in *; do            if cd $d; then              mv $d $TOP/$y-$m-$d -R             fi          done          cd .. && rmdir $m        fi      done      cd .. && rmdir $y    fi  done  


  $ fn="/media/drive/folder/2014/06/14/name.jpg" ; \  echo "mv $fn $(echo $fn | sed -re 's,([0-9]+)/,\1-,g')"  mv /media/drive/folder/2014/06/14/name.jpg /media/drive/folder/2014-06-14-name.jpg  
  $ find -type f | tee LISTOFFILES.txt  $ cat LISTOFFILES.txt | while read p  ; do # loop through all files, one at a time  f="${p##*/}" ; bn=${f%%\.*} ; op="${p%/*}/" ;   echo -e "$f\n$bn\n$op"  # $p - complete path to original file  # $f - filename with extension  # $bn - basename, filename without extension  # $op - orignal PATH, filename and extensions stripped off    # add your conversion here - based on the above  # mkdir -p "$p" # probably required  # mv "$p" "..." #   done  

Now, if you read the above THOROUGHLY you will find all bits and pieces you need to accomplish this task.

As I cannot tell how you HAVE IT nor HOW YOU WANT IT - I cannot finish it for you.

has TWO Bash guides to read and look through - have a go.

I'm leaving it here. This is not a service, I did it due to curiosity only.
And remember - there MAY be faults in there, as I have not tested it fully.
YOU may introduce faults you didn't think of... :-)

Good luck! ;-) you need it.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »