Jon Griffith
Jon Griffith

Reputation: 183

How to incorporate conditions in a for loop to create folder names based on file dates

I've managed to create a script that loops through each file in a folder, extracts the year, month, and day, then creates a folder structure for that.

For a group of files, I end up with folders like this:

2019
  02 (February)
    01 (Day 1)
  03
    01
    02

Question: How do I incorporate a comparison to already existing folders and stop the script from performing the same action over and over again? I.E., MKDIR 2019, MKDIR 2019, etc.

If there are 10 files that were created in 2019, then the script creates the folder on the first loop, and then the next 9 iterations reports an error as the folder already exists, despite it still giving the desired result.

The same happens in the month folders and the day folders.

Here is what I currently have:

#!/bin/bash

for file in *

do

YEAR=$(date -r ${file} +"%Y")
MONTH=$(date -r ${file} +"%m")
DAYOFMONTH=$(date -r ${file} +"%d")

        for year in $YEAR
        do

                mkdir $YEAR

                for month in $MONTH
                do
                mkdir $YEAR/$MONTH 
                done

                        for day in $DAYOFMONTH
                        do
                        mkdir $YEAR/$MONTH/$DAYOFMONTH
                        done

        done

cp ${file} $YEAR/$MONTH/$DAYOFMONTH

done

Upvotes: 1

Views: 852

Answers (1)

KamilCuk
KamilCuk

Reputation: 141200

Just pass -p option to mkdir to remove the error when a directory already exists.

Alternatively check if a directory already exists before creating it, like:

if [ ! -d "$dir" ]; then
      mkdir "$dir"
fi

Notes:

  • to avoid errors, for example with handling filenames with whitespaces, quote your variables expansions.
  • you don't need to iterate over the year, month, dayofmonth, there is nothing to iterate over. There is one modification time for a file, one year, one month, one dayofmonth, not multiple for each file.. There is nothing to iterate over, you are iterating over one element.
  • Note that your loop for file in * will iterate over the directories too, not only over files. So after the first time you run your script, when you'll run it the next time, it will iterate over the created year directories.
  • I could suggest to replace date -r with stat -c + date -d for portability. date -r may not work everywhere.

Just:

for file in *; do
   dest="$(date -r "$file" +"%Y/%m/%d")"
   mkdir -p "$dest"
   cp "$file" "$dest"
done

Upvotes: 1

Related Questions