grep ^"string"

 
Allanm
Super Advisor

grep ^"string"

Hi!

I am looking to grep for file starting with a certain string. While doing -

find . -mtime 2 -name approve* |xargs grep -l ^"valid data format"

I am not getting the correct results. Can someone provide a better solution?

Thanks,
Vaibhav
5 REPLIES 5
Prasanth V Aravind
Trusted Contributor

Re: grep ^"string"


find . -mtime 2 -name "approve*" |xargs grep -l ^valid | grep data | grep format

OR


find . -mtime 2 -name "approve*" |xargs grep -l "^valid data format"

Prasanth V Aravind
Trusted Contributor

Re: grep ^"string"

Vaibhav,

its working fine on my machine..

[root@vm1 ~]# find . -name "approve*" | xargs grep -i "^valid data format"
./approve:valid data format hai a
./Desktop/approve:valid data format hai a

Gudluck
Prasanth
Dennis Handly
Acclaimed Contributor

Re: grep ^"string"

grep "^X" looks for any line that starts with that string. To do only the first line, you must do some scripting:
#!/usr/bin/ksh
while [ $# -gt 0 ]; do
head -1 $1 | grep -q "^valid data format"
if [ $? -eq 0 ]; then
echo $1
fi
shift
done

With this script, you can toss the xargs:
find . -mtime 2 -name "approve*" -exec head_grep +
James R. Ferguson
Acclaimed Contributor

Re: grep ^"string"

Hi Vaibhav:

If, as Dennis interprets your question, you only want results if the first line of any file matches, you could do:

# find . -type f -mtime 2 -name "approve*" -exec perl -we 'while (<>) {if ($.==1) {/^valid data format/ and print $ARGV,":",$_};close ARGV}' {} +

This should be quite efficient since multiple arguments from the find() results are passed to the Perl script. The use of '+' with 'find...-exec {} +' works analogously to 'xargs' in bundling arguments and thus reducing the number of processes created.

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor

Re: grep ^"string"

>JRF: The use of '+' with find works analogously to xargs in bundling arguments and thus reducing the number of processes created.

Except -exec + does a much better job with larger buffers.
find . -exec echo + > find.output
find . | xargs echo > xargs.output

In the above case with ~35 Kb output, there are 1 vs 18 calls to echo.
And xargs(1) has this bogus limitation:
$ find . | xargs -s 40000 echo
xargs: 0 < max-cmd-line-size <= LINE_MAX: -s 40000
And using "-n 40000" isn't fully honored.