1

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.

//Ola

2
  • an example would be better. Do you want to rename files? Jun 14, 2014 at 14:37
  • Do you mean you already have a structure and you want to flatten it? Do you want to create one directory per day? Should the path change, but the filenames stay?
    – choroba
    Jun 14, 2014 at 15:08

4 Answers 4

5

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.

2
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
0
0

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
0
$ 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.

http://www.tldp.org/guides.html
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.

1
  • When you don't have enough details to confidently answer a question, there's a fair chance that the question should be closed as Unclear. Apr 22, 2020 at 9:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .