2

If I run the following command

find ./dir -type f -newermt 2017-04-01 ! -newermt 2018-06-30 -printf "%TY/%Tm/%Td  %TH:%TM:%.2TS   %p\n" -exec grep -E -l "pattern" {} \; | sort -n;

will return this:

./dir_2/01.py</br>
./dir_2/03.py</br>
./dir_2/05.py</br>
2018/05/08  08:44:55   ./dir_2/01.py</br>
2018/05/08  08:45:03   ./dir_2/02.py</br>
2018/05/08  08:45:13   ./dir_2/03.py</br>
2018/05/08  08:45:21   ./dir_2/04.py</br>
2018/05/08  08:45:28   ./dir_2/05.py</br>

but I would like to have this: (because only these three file contain "pattern") (including date and timestamp)

2018/05/08  08:44:55   ./dir_2/01.py</br>
2018/05/08  08:45:13   ./dir_2/03.py</br>
2018/05/08  08:45:28   ./dir_2/05.py</br>

I use Ubuntu version: 14.04.5 LTS trusty and find version (GNU findutils) 4.4.2.

3

Putting the -exec grep [...] before the -printf and sending the stdout of grep to /dev/null (needs sh -c) works well:

find ./dir -type f -newermt 2017-04-01 ! -newermt 2018-06-30 \
  -exec sh -c 'grep -E -l "pattern" "{}" 1>/dev/null' \; \
  -printf "%TY/%Tm/%Td  %TH:%TM:%.2TS   %p\0" | \
sort -z -n | tr '\0' '\n'

Thanks to your question I learned something new. I did not even know that it is possible to filter find results like that.

Another option would be to use some piping and xargs. First performance tests show me that this is even a little bit faster although I wonder why:

find ./dir -type f -newermt 2017-04-01 ! -newermt 2018-06-30 -print0 | \
  xargs -0 -i -P6 grep -E -l "pattern" "{}" | \
  xargs -i find "{}" -printf "%TY/%Tm/%Td  %TH:%TM:%.2TS   %p\0" | \
sort -z -n | tr '\0' '\n'

(Note the -P6 --> Running the grep command in parallel.)

  • If you pipe filenames, always use the null character to make sure the word splitting is done correctly: find … -print0 | xargs -0 … | sort -z … – dessert May 9 '18 at 13:56
  • Good suggestion, updated the answer. But wouldn't grep break filenames including a newline anyways ? – pLumo May 9 '18 at 14:30
  • Let's try! – dessert May 9 '18 at 15:06
  • Wait, do you really need the tr? sort -z means take the input null-delimited, that should (IMO) not affect the output. – dessert May 9 '18 at 15:12
  • Actually I tried and it didnt work – pLumo May 9 '18 at 16:31

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.