3

I this is what I what I'm trying to end up with (except working)

find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 egrep -vZ 'vvv|iii'

What am I doing wrong?

$ ll
total 0
-rw-rw-r-- 1 yyy yyy 0 Sep 18 10:36 iii.txt
-rw-rw-r-- 1 yyy yyy 0 Aug 29 10:35 old1.txt
-rw-rw-r-- 1 yyy yyy 0 Aug 29 10:35 old2.txt
-rw-rw-r-- 1 yyy yyy 0 Aug 29 10:35 old3.txt
-rw-rw-r-- 1 yyy yyy 0 Nov 16 09:36 vvv.txt
-rw-rw-r-- 1 yyy yyy 0 Nov  5 09:41 young.txt 
$    find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 egrep -viZ 'vvv|iii'
$    find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 egrep -vilZ 'vvv|iii'
$    find ./ -mindepth 1 -type f -mtime +60 -print0 
./old3.txt./old1.txt./old2.txt$    find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 egrep 'old'
$    find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 grep 'old'
$    find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 grep 'o'
$    find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 grep '.*o.*' 
$    find ./ -mindepth 1 -type f -mtime +60 | xargs egrep 'o'
$    find ./ -mindepth 1 -type f -mtime +60 | xargs egrep '.*o.*'
$    find ./ -mindepth 1 -type f -mtime +60
./old3.txt
./old1.txt
./old2.txt
$    find ./ -mindepth 1 -type f -mtime +60 | grep 'o'
./old3.txt
./old1.txt
./old2.txt
$    find ./ -mindepth 1 -type f -mtime +60 | xargs grep 'o'
$    find ./ -mindepth 1 -type f -mtime +60 -print | xargs grep 'o'
$    find . -name "*.txt" | xargs grep "old"
$    find . -name "*.txt"
./old3.txt
./vvv.txt
./iii.txt
./old1.txt
./old2.txt
./young.txt
$ find ./ | grep 'o'
./old3.txt
./old1.txt
./old2.txt
./young.txt
$ find ./ | xargs grep 'o'
$

I need the grep because the exclude list will come from a file in the end so just using find to filter isn't quite enough. I'd like the grep to return a NUL terminated list, too. And I am going to pipe the result of this to something else after so I don't know if the find option -exec would be appropriate.

Things I've looked at:

$ bash -version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
$ cat /proc/version
Linux version 2.6.18-371.8.1.0.1.el5 (mockbuild@ca-build56.us.oracle.com) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-54)) #1 SMP Thu Apr 24 13:43:12 PDT 2014

disclaimer: I do not have a lot of linux or shell experience.

1 Answer 1

3

It looks like you want to grep on filenames, buf if you do:

find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 egrep -vZ 'vvv|iii'

the xargs actually presents the list of files coming out of find as argument to egrep.

What you should do to handle the NUL terminated input (from -print0)

find ./ -mindepth 1 -type f -mtime +60 -print0 | xargs -0 grep -EvzZ 'vvv|iii'

(egrep is deprecated, that is why I changed it to grep -E)

From man grep:

   -z, --null-data
          Treat the input as a set of lines, each  terminated  by  a  zero
          byte  (the  ASCII NUL character) instead of a newline.  Like the
          -Z or --null option, this option can be used with commands  like
          sort -z to process arbitrary file names.

   -Z, --null
          Output  a  zero  byte  (the  ASCII NUL character) instead of the
          character that normally follows a file name. 

So you need both -z and -Z

6
  • thanks for the deprecated egrep info, too. Nov 17, 2014 at 16:22
  • @gloomy.penguin I didn't understand why you can't use ! -name "*vvv*" ! -name "*iii*" find option ?
    – Costas
    Nov 17, 2014 at 16:29
  • @gloomy.penguin egrep is not going to go away soon but for scripts etc it is better to use approved forms. I still need to get used to typing grep -F instead of fgrep trying to get rid of 25 years of muscle memory.
    – Anthon
    Nov 17, 2014 at 16:31
  • @Costas - I guess I could. This gets parameterized in a bash script. I considered it but I wanted to know what I was doing wrong with this, too. It might eventually be a long list to generate/concatenate of excluded things, though.... do commands have a length limit (or max number of arguments)? Nov 17, 2014 at 16:31
  • @gloomy.penguin yes there is a limit: xargs --show-limits show the ones for your system. Or getconf ARG_MAX
    – Anthon
    Nov 17, 2014 at 16:51

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.