Thursday, June 4, 2009
Remove files without match using bash grep
I have already discussed in one of my earlier post how we can find the files which do not contain a particular pattern (string).
As I mentioned in that particular post:
"Well, when I first heard of this requirement; I just thought I will use "grep -vl pattern" piped with xargs to a regular find command (i.e. "find . -type f | xargs grep -vl pattern")
(-l : Suppress normal output; instead print the name of each input file from which output would normally have been printed.)
Then I realized that "grep -v" only works in line level, i.e. a file which contain the "pattern" in some line(s) may also contain some line(s) which "do not" contain that "pattern"; so as a whole that file will also be in the list of files which "do not" contain the "pattern" even though it contains the pattern."
From GREP(1) man pages:
-L, --files-without-match
Suppress normal output; instead print the name of each input file from which no out-put would normally have been printed. The scanning will stop on the first match.
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected. Also see the -s or --no-messages option.
So to remove or delete the files which do not contain the pattern or string "hello"
$ find . -type f -exec grep -L "hello" {} \; | xargs rm
or
$ find . -type f \! -exec grep -q "hello" {} \; -print | xargs rm
Labels:
Bash,
bash shell newbie,
exec,
find command,
Linux Commands,
xargs
Subscribe to:
Post Comments (Atom)
© Jadu Saikia www.UNIXCL.com
3 comments:
Nice one Saikia, I think we can do it inside find itself.
find . -type f -exec grep -L "hello" {} \; -exec rm {} \;
Hey Mahesh, thanks for your comment. But that nested -exec as you mentioned does not work for me, I have tried that. Also do you have any idea how we can specify multiple(nested) operation to xargs ? Keep in touch. Thanks Again.
Do you have GNU find. This is a GNU feature ...
for nesting, this should be helpful
find -type f -print | xargs -I {} -i ksh -c 'cp {} /tmp; echo "{} copied to /tmp"'.
Not sure whether your xargs will support this, it worked for me.
Post a Comment