1

I am currently trying to write a script that organizes a list of files into subdirectories by their dates. The dates are contained on the first line of every file in the format YYYY-MM-DD. I have extracted the first line from every file using the head command and replaced the - with / so it becomes YYYY/MM/DD. This is so I can use it as file path.

I then want to create subdirectories YYYY>MM>DD where for example, the file containing the date 2015/10/19 is stored in the file path ./2015 -> ./2015/10 -> ./2015/10/19. These subdirectories should be created in ~/fileList/.

This is the code I have so far.

for file in ~/fileList/*
do
   head -1 $file | tr "-" "/")
done

This is a sample file

2001-02-03
Thursday
Paris
44952

I'm struggling to find a way to create the subdirectories and store each file in the correct directory. Any code suggestions would be much appreciated.

I am using the bash shell.

1
  • if you can convert a date into an epoch second and back. that would simplify things as date comparison becomes easier when its just a number.
    – john-jones
    Oct 21, 2021 at 15:26

1 Answer 1

2

The following should do:

for file in ~/fileList/*
do
    newpath=$(head -1 "$file" | tr '-' '/')
    mkdir -p "$newpath"
    echo "would now execute 'mv $file $newpath'"
done

This will store the transformed date in the variable $newpath and create that directory along with any missing parents if it doesn't yet exist. The subdirectory will be created in the directory where you run the script.

In its current form it will print the command that would be executed. When you are satisfied, change to

mv "$file" "$newpath"

Update: Since you stated that the target directories will be located below the source directory where your files originally reside, checks are necessary to ensure that should you run the script multiple times, it doesn't stumble upon these newly-generated entries.

  • If you can identify the files by their extension (e.g. .txt), you can make the loop more speficic:
    for file in ~/fileList/*.txt
    do
        newpath=~/fileList/$(head -1 "$file" | tr '-' '/')
        ...
    done
    
  • Otherwise, one way is to only accept regular files as operands:
    for file in ~/fileList/*
    do
        if [[ ! -f $file ]]; then continue; fi
        newpath=~/fileList/$(head -1 "$file" | tr '-' '/')
        mkdir -p "$newpath"
        mv "$file" "$newpath"
    done
    
0

You must log in to answer this question.

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