Reputation: 513
I have a dir structure like
$ ls /comp/drive/
2009 2010 2011 2012 2013 2014
$ ls 2009
01 02 03 04 05 06 07 09 10 11 12
$ ls 2013
01 02 04 05 06 08 09 10 12
$ ls 2013/04/*.nc
file4.nc file44.nc file45.nc file49.nc
There are dirs like years and each year there are few months dirs and inside are .nc files.
What I want to do is get the array of filenames provided start and end years/months.
e.g. sYear=2011; eYear=2013; sMonth=03; eMonth=08
So, I want to get the array of all filenames from year 2011/03 to 2013/08 only without going inside the dirs.
Any bash trick?
Upvotes: 1
Views: 243
Reputation: 295403
sYear=2011; eYear=2013; sMonth=03; eMonth=08
# prevent bugs from interpreting numbers as hex
sMonth=$(( 10#$sMonth ))
eMonth=$(( 10#$eMonth ))
files=( )
for (( curYear=sYear; curYear <= eYear; curYear++ )); do
# include only months after sMonth
for monthDir in "$curYear"/*/; do
[[ -e $monthDir ]] || continue # ignore years that don't exist
curMonth=${monthDir##*/}
(( curMonth )) || continue # ignore non-numeric directory names
(( curYear == sYear )) && (( 10#$curMonth < sMonth )) && continue
(( curYear == eYear )) && (( 10#$curMonth > eMonth )) && continue
files+=( "$monthDir"/*.nc )
done
done
printf '%q\n' "${files[@]}"
Upvotes: 3
Reputation: 6449
Try this:
sYear=2011
sMonth=03
eYear=2013
eMonth=08
shopt -s nullglob
declare -a files
for year in *; do
(( ${year} < ${sYear} || ${year} > ${eYear} )) && continue
for year_month in ${year}/*; do
month=${year_month##*/}
(( ${year} == ${sYear} && ${month##0} < ${sMonth##0} )) && continue;
(( ${year} == ${eYear} && ${month##0} > ${eMonth##0} )) && continue;
files+=(${year_month}/*.nc)
done
done
echo "${files[@]}"
# printf "$(pwd)/%q\n" "${files[@]}" # for full path
Upvotes: 2