Operating System - HP-UX
1753884 Members
7570 Online
108809 Solutions
New Discussion юеВ

Re: find and xargs question

 
SOLVED
Go to solution
Allanm
Super Advisor

find and xargs question


I am issuing the following command :

find . -name "*"|xargs grep 3300

which gives me a listing of files having 3300 in their text but the I dont want to see log files . How to modify this command in order for me not to have log files .

I tried "find . -name "*"|xargs grep 3300|xargs grep -v *log* ( did not work )

find . -name "*"|xargs grep 3300|grep -v *log*
but this also gives me log files.
9 REPLIES 9
A. Clay Stephenson
Acclaimed Contributor

Re: find and xargs question

It's dumb to use grep for this when find will do it all (I also assume you just want reguler files [-type f]):

find . -type f \( -name '*3300*' -a ! -name '*log*' \)
If it ain't broke, I can fix that.
Oviwan
Honored Contributor

Re: find and xargs question

Hey

if you will find the string only in the files of the current directory you can use this:

$grep 3300 $(ls | grep -v log)

Hope this helps

Regards
James R. Ferguson
Acclaimed Contributor

Re: find and xargs question

Hi:

...and NOTE carefully that Clay quoted "*log*".

This prevents the shell from expanding "*log*" before 'find' sees the argument and giving you an obtuse error when failing.

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor
Solution

Re: find and xargs question

You need to exclude log, either with grep or add it to find:
$ find . -type f ! -name "*log*" -exec grep 3000 +

To exclude log, you must grep -v before xargs.
The problem with your "grep -v *log*", is that grep takes a regexp(5) and not a file matching pattern. And as JRF mentions, you would need to quote it, IF those "*" were required.

>Clay: find . -type f \( -name '*3300*' -a ! -name '*log*' \)

The string 3300 is in the file, not the name.
And \( -a \) aren't required.

>Oviwan: $grep 3300 $(ls | grep -v log)

While this does what you say, you can use the shell's file name generation directly:
$ grep 3300 !(*log*)
Allanm
Super Advisor

Re: find and xargs question

-name '*3300*' --> does this mean any files having 3300 in their file-name or in the body of the file coz now I am getting nothing.
Allanm
Super Advisor

Re: find and xargs question

find . -name "*"|grep -v log |xargs grep "3300"

This worked for me -

Thanks Dennis!
Allanm
Super Advisor

Re: find and xargs question

Thanks Dennis!
Dennis Handly
Acclaimed Contributor

Re: find and xargs question

>-name '*3300*' --> does this mean any files having 3300 in their file-name

Yes, in the filename. But you didn't want that. ;-)

>find . -name "*"|grep -v log |xargs grep "3300"

You do know you don't need "-name" above. And you can put the grep -v log into another ! -name. And you can use -exec ... + instead of xargs?
A. Clay Stephenson
Acclaimed Contributor

Re: find and xargs question

Sorry I misread your posting. You need to filter the log files out with "! -name '*log*' and then use grep for the 3300.

find . -type f ! -name '*log*' | while read F
do
grep -q "3300" "${F}"
GSTAT=${?}
if [[ ${GSTAT} -eq 0 ]] # match
then
echo "${F}"
fi
done

Now, a better test though most expensive is to first send the filename to the file command to see if it is some sort of text file before using grep. On some platforms grep will crash when fed non-text files for breakfast.

find . -type f ! -name '*log*' | while read F
do
file "${F}" | grep -q -i "text"
GSTAT1=${?}
if [[ ${GSTAT1} -eq 0 ]
then # text file; ok to grep
grep -q "3300" "${F}"
GSTAT2=${?}
if [[ ${GSTAT2} -eq 0 ]]
then # match
echo "${F}"
fi
fi
done


Note that I was careful to quote your filenames because some evil person just might have embedded whitespace in them.
If it ain't broke, I can fix that.