Bash – How to Reorganize Files by Date in Filenames

bashscriptingshellshell-script

I am working with thousands of files whose names contain sequential dates ranging from 2001-01-01 to 2020-12-31.

A sample of such files can be seen below:

gpm_original_20010101.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-1_radius-500km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-2_radius-250km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-3_radius-150km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-4_radius-75km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-5_radius-30km.nc
.
.
.
gpm_original_20010131.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-1_radius-500km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-2_radius-250km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-3_radius-150km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-4_radius-75km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-5_radius-30km.nc

and so on until 2020-12-31. What I need to do is to reorganize these files into new folders based on years and months.

The directory tree needs to follow the logic year with sub-directories months, like this:

2001
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12

2002
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12

and so on. And the files should be moved to these directories based on the equivalent date in their filenames. For example: all files containing 200101xx in their names should be moved to the 2001/01 folder.

What is the most straightforward way to achieve this using bash?

Best Answer

Here is my proposal if I understood correctly:

for i in *.nc; do 
  [[ "$i" =~ _([0-9]{8})[_.] ]] && d="${BASH_REMATCH[1]}"
  mkdir -p "${d:0:4}/${d:4:2}"
  mv "$i" "${d:0:4}/${d:4:2}"
done
Related Question