LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 02-18-2009, 02:03 PM   #1
wakeboarder3780
Member
 
Registered: Mar 2006
Distribution: Ubuntu 6.10
Posts: 112

Rep: Reputation: 15
Grep an entire file but must contain multiple words


Hi,
Just wanted to get a bit better at my grep skills. Basically I want to return a filename if it contains the word 'element' and the word 'name' and the word 'foo' and the word 'bar'. If the file contains all these words, I want to know what file it is.

I have been trying the following which seems to work but it is ungodly slow. I will be searching a boatload of files so it would be nice if it were faster. I'm sure there is a built in better way for grep to handle this (some regex magic I dont know about).

$ find . -iname "*.txt" -print0 | xargs -0 -n 1 grep Tag | grep Read

This doesn't print out the filename, but kind of works. Suggestions for faster results and perhaps printing out the filename?
 
Old 02-18-2009, 02:10 PM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
It's easy if the words can appear in order.....

Code:
<somecommands>|grep "*element*name*foo*bar*"
Lazy way out:

Code:
<somecommands>|grep element|grep name|grep foo|grep bar
(keywords must all be present and can be in any order)

Last edited by pixellany; 02-18-2009 at 02:12 PM.
 
Old 02-18-2009, 04:54 PM   #3
rizwanrafique
Member
 
Registered: Jul 2006
Distribution: Debian, Ubuntu, openSUSE, CentOS
Posts: 147

Rep: Reputation: 19
I would use something like:
Code:
find ./|grep -l <string>|xargs grep -l <string2>|xargs -l grep <string3> ...
 
Old 02-18-2009, 07:45 PM   #4
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,965
Blog Entries: 11

Rep: Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865
Code:
find  -type f | awk '/foo/ && /bar/ && /baz/'
 
Old 02-18-2009, 08:20 PM   #5
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 12,130

Rep: Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986
OP wants the filename - and won't you need to -exec that Tink ?
Code:
find  -type f -exec awk '{if (/foo/ && /bar/ && /baz/) print FILENAME}' {} \;
 
Old 02-18-2009, 08:33 PM   #6
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,965
Blog Entries: 11

Rep: Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865
Hmmm ... I must have misunderstood him ... I thought he was looking
for files with foo, bar and baz in the name. :}



If he's looking for files that have foo, bar and baz inside them (anywhere)
and then print the filename none of the approaches above will quite do ...
they'll only work if foo, bar and baz are on one line, not anywhere in
the file ...


That'll be more like?
Code:
find  -type f -exec awk 'BEGIN{foo=0;bar=0;baz=0}/foo/{foo++}/bar/{bar++}/baz/{baz++}END{if(foo>0 && bar>0 && baz>0){print FILENAME}}' {} \;
Completely untested, of course...
 
Old 02-18-2009, 09:57 PM   #7
JulianTosh
Member
 
Registered: Sep 2007
Location: Las Vegas, NV
Distribution: Fedora / CentOS
Posts: 674
Blog Entries: 3

Rep: Reputation: 90
good job! works great! Never used awk that way so I'll be storing that little goodie away for future use!
 
Old 02-19-2009, 01:43 PM   #8
wakeboarder3780
Member
 
Registered: Mar 2006
Distribution: Ubuntu 6.10
Posts: 112

Original Poster
Rep: Reputation: 15
That is precisely what I was looking for, thank you very much for your solution. I'll chalk awk up on my list of programs to learn (it looks quite large)
 
Old 02-19-2009, 01:58 PM   #9
wakeboarder3780
Member
 
Registered: Mar 2006
Distribution: Ubuntu 6.10
Posts: 112

Original Poster
Rep: Reputation: 15
Any ideas for how to get this in a script so it could be used like the following:

find . -iname "*.whatever" -type f | myScript any number of strings

this would be super useful. I can of course read a bunch and do my best as well
 
Old 02-19-2009, 02:11 PM   #10
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,965
Blog Entries: 11

Rep: Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865
Now I won't sit down and write this for you ... ;} ... sorry!

But I'd devise a shell script that evaluates a switch -t (for type)
for your "*whatever", and accepts everything else on the command line
as your "any number of strings".

Then (in pseudo code) I'd
write "any number of strings" to a stringfile, one per line.
invoke find withe the "whatever" parameter.
have an awk script that reads stringfile, and assigns the
elements to an array in the BEGIN section.
for each line that awk processes iterate over the array and
check whether any item is part of the line, if so increment
it.
in the END section loop over the array, skip the record as
soon as a zero value occurs. If the loop doesn't exit, print
the file name.
 
Old 02-19-2009, 04:46 PM   #11
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 12,130

Rep: Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986Reputation: 986
I was thinking at the time 3 was about the limit for that approach and it was about time for a file of values and an array. @wakeboarder3780 do a google on "awk" an "associative array" to get an idea of what you can do - for example this article.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Grep words and paste is on the same line say_hi_ravi Programming 7 10-31-2008 06:56 AM
shell script having multiple grep statements-I want input file to be read only once mukta9003 Linux - Newbie 4 08-27-2008 12:58 AM
[Solaris 9] find and grep entire disk noir911 Solaris / OpenSolaris 3 02-13-2008 05:51 PM
GREP - reg exp to find words ending with .V and .TO vikram_cvk Linux - Server 5 12-22-2006 01:47 PM
Can grep filter out words? extrasolar Linux - General 1 07-20-2006 03:14 PM


All times are GMT -5. The time now is 10:41 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration