I need to get the list of files(.log/.lst) present in a directory($logfolder) whose creation date is in a specific $year and $month

stat  --format='%y %n'  $logfolder/* |
  grep "$year-$month-"|
  awk -F' ' '{print $4}'|
  grep 'log$\|lst$' > $archivepath/filesToArchive

This doesn't work when I query the command to a folder where there are too many files. I get the following error:

-bash: /usr/bin/stat: Argument list too long
  • Your grep will catch both files with the date in the name and the stat date. – Matt Jun 25 '14 at 16:39
  • Your awk will miss files with spaces in the name. – Matt Jun 25 '14 at 16:40

For a funny possibility, if your find handles -newerXY, use it! For example to get the files from year 1977 and month October:

find "$logfolder" \( -name '*.log' -o -name '*.lst' \) -newermt "1977-10-01" \! -newermt "1977-10-01 +1 month"


As you already have the variables year and month it's straightforward to write as:

find "$logfolder" \( -name '*.log' -o -name '*.lst' \) -newermt "$year-$month-01" \! -newermt "$year-$month-01 +1 month"

Only one find command! amazing!

  • 1
    +1 Since the OP's stat is of the GNU variant, his find more than likely supports -newermt as well. – Stéphane Chazelas Jun 25 '14 at 18:44

I would do it like this:

find "$logfolder" \( -name '*.log' -o -name '*lst' \) -printf "%TB\t%TY\t%p\n" |
     awk '$1==m && $2==y' m="$month" y="$year" | cut -f 3- 


By grouping the two -name calls in parentheses, you can combine them with the -o (or) flag. This will make find look for either .log or .lst files. The -printf (a GNU extension) prints the file's modification month (%TB), then its modification year (%TY) and then its path (%p), with a tab (\t) between each field.

The awk simply checks that the 1st field (the month) is the same as $month and the second is the same as $year.

The cut removes the first two fields (the month and year) and prints everything from the 3rd field on.

I tested the above by creating files modified in December 2012 (and set $month to "December" and $year to 2012):

$ touch -d "December 13 2012" {a,b,c}{.lst,.log}
$ touch c.lst a.log ## c.lst and a.log now have today's modification date.
$ find $logfolder \( -name '*.log' -o -name '*lst' \) -printf "%TB\t%TY\t%p\n" |
  awk '$1==m && $2==y' m="$month" y="$year" | cut -f 3-

(note that it assumes file and directory names don't contain newline characters).


Try this:

find $logfolder -type f -exec stat --format='%y %n' "{}" + |
  grep "$year-$month-"|
  awk -F' ' '{print $4}'|
  grep 'log$\|lst$' > $archivepath/filesToArchive
  • grep "^$year-$month-" so you don't the string in file names – Matt Jun 25 '14 at 16:29
  • @mtm: I only use find to fix the error Argument list too long. It's very hard to know exactly what the OP want. – cuonglm Jun 25 '14 at 16:33
  • No worries.. will comment on OP – Matt Jun 25 '14 at 16:39
  • 1
    awk can do grep's job and more, you almost never need to pipe awk and grep together. Note that your last grep command is not portable/standard. – Stéphane Chazelas Jun 25 '14 at 18:50

ls -lh *.log *.lst logfolder | grep year | grep month

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.