MacOS – How to replace a folder that’s name is a date i.e. YYYYMMDD with folder hierarchy of year, month, date

applescriptautomatorfoldersmacosterminal

I have a list of folders which have dates for names. The dates are in the format YYYYMMDD (e.g. 20150129). Within these folders are text documents which are related to that specific date.

I would like to restructure them in a folder hierarchy going from year to month to date, and to move the text documents into the corresponding 'date' folder lower down in the hierarchy.

In other words I would like the 'root' folder to be named after the year like 2015, and then create sub-folders named with months like 01, and then create further sub-folders named with dates like 29 which hold the corresponding text documents.

So the path would look like 2015/01/29/file.txt or 2015>01>29>file.txt.

I have taken a look at Automator and it seems that something like this is not possible although I could be wrong, so I would like to know…

  1. Is there some easy solution to this problem that any layman can understand, for example an Automator workflow, or does this require some understanding of terminal commands and regular expressions?

  2. How would one solve this problem provided there is in fact a solution?

Best Answer

Assuming all these YYYYMMDD folders are part of the same parent directory you could run

cd PARENT_DIRECTORY
for d in */; do
    [[ $d =~ [0-9]{8}/ ]] || continue
    mkdir -p -- "${d:0:4}/${d:4:2}"
    mv -- "$d" "${d:0:4}/${d:4:2}/${d:6:2}"
done
  • The for d in */; do loop reads all directory entries, the trailing / ensures that only directory names actually match
  • [[ $d =~ [0-9]{8}/ ]] tests whether the current entry consists of 8 digits, and continues with the next entry if not
  • ${d:0:4}/${d:4:2}/${d:6:2} uses parameter expansion within bash to create a string containing the new path
  • The -- in both mkdir and mv prevents problem in case the directory or file name starts with a -. This can't happen here but it's probably good practice anyway.

Thanks to @terdon and @user3439894 for ideas on how to improve the original script.