Home > Blockchain >  How to use wildcards to list files between certain dates in bash?
How to use wildcards to list files between certain dates in bash?

Time:08-03

A directory I work with has the following files in it:

COF_34_Evaluation_first_MODELASC_v1_f_19790101-19801231.nc
COF_34_Evaluation_first_MODELASC_v1_f_19810101-19851231.nc
COF_34_Evaluation_first_MODELASC_v1_f_19860101-19901231.nc
COF_34_Evaluation_first_MODELASC_v1_f_19910101-19951231.nc
COF_34_Evaluation_first_MODELASC_v1_f_19960101-20001231.nc
COF_34_Evaluation_first_MODELASC_v1_f_20010101-20051231.nc
COF_34_Evaluation_first_MODELASC_v1_f_20060101-20101231.nc
COF_34_Evaluation_first_MODELASC_v1_f_20110101-20151231.nc
COF_34_Evaluation_first_MODELASC_v1_f_20160101-20181231.nc

I'd like to only list the ones which date between 19950101 to 20171231, so that would be the following files:

COF_34_Evaluation_first_MODELASC_v1_f_19910101-19951231.nc
COF_34_Evaluation_first_MODELASC_v1_f_19960101-20001231.nc 
COF_34_Evaluation_first_MODELASC_v1_f_20010101-20051231.nc 
COF_34_Evaluation_first_MODELASC_v1_f_20060101-20101231.nc 
COF_34_Evaluation_first_MODELASC_v1_f_20110101-20151231.nc 
COF_34_Evaluation_first_MODELASC_v1_f_20160101-20181231.nc

I use the following script:

ls directory/*[1991-2018]1231.nc 

The result is not as I expect.

My question is How I can use wildcards properly to list the requested files?

CodePudding user response:

With your shown samples and attempts, please try following find command with using posix-egrep option to allow regex to find the range.

find . -regextype posix-egrep -regex ".*_f_(?:199501[0-9][1-9]|199[6-9][0-9]{4}|2[0-1][0-9]{6}|21[0-9]{6}|(?:22(?:0[0-9]{5}|1[0-6][0-9]{4}|1700[0-2][0-9]|170031)))-[0-9] \.nc"

I have tested with minimal samples(shown one only as of now), you could do thorough testing on same.

Here is the Online demo for above used regex.

CodePudding user response:

Here is an approach using bash arithmetic that compares from and to dates with the given range:

find . -name '*.nc' -exec bash -c '
for f; do
   IFS='-.' read n1 n2 _ <<< "${f##*_}";
   (( (n1>=19950101 || n2>=19950101) && (n1<=20171231 || n2<=20171231) )) && echo "$f";
done' _ {}  

./COF_34_Evaluation_first_MODELASC_v1_f_19960101-20001231.nc
./COF_34_Evaluation_first_MODELASC_v1_f_20160101-20181231.nc
./COF_34_Evaluation_first_MODELASC_v1_f_20060101-20101231.nc
./COF_34_Evaluation_first_MODELASC_v1_f_20010101-20051231.nc
./COF_34_Evaluation_first_MODELASC_v1_f_19910101-19951231.nc
./COF_34_Evaluation_first_MODELASC_v1_f_20110101-20151231.nc
  • Related