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:
- https://stackoverflow.com/questions/1362615/how-to-find-files-containing-a-string-using-egrep
- http://www.unixmantra.com/2013/12/xargs-all-in-one-tutorial-guide.html
$ 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 ([email protected]) (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
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
-
@gloomy.penguin I didn't understand why you can't use
! -name "*vvv*" ! -name "*iii*"
find
option ?Costas– Costas2014年11月17日 16:29:15 +00:00Commented 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 typinggrep -F
instead offgrep
trying to get rid of 25 years of muscle memory.Anthon– Anthon2014年11月17日 16:31:02 +00:00Commented 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)?gloomy.penguin– gloomy.penguin2014年11月17日 16:31:25 +00:00Commented Nov 17, 2014 at 16:31
-
@gloomy.penguin yes there is a limit:
xargs --show-limits
show the ones for your system. Orgetconf ARG_MAX
Anthon– Anthon2014年11月17日 16:51:05 +00:00Commented Nov 17, 2014 at 16:51 -
@gloomy.penguin I'm not sure in command length limitation (suppose is the same as for other command and depends of your system) but you can use
! -regex ".*\(vvv\|iii\).*"
option which much shorter. Or to totally avoid length limitation put list of files and list of patterns in two files and then usegrep -fv pattern.list file.list
Costas– Costas2014年11月17日 16:55:50 +00:00Commented Nov 17, 2014 at 16:55