LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-03-2003, 09:08 AM   #1
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Rep: Reputation: 0
Shell programming - grep??


Hi..

Is there a command out there that will search for multiple patterns in each line of a file?

what i mean by that is....

if i was to search a file for the patterns "Hello" and "Goodbye", is there a command out there that will bring up all the lines in that file that contain only "Hello" AND "Goodbye" on the same line (not every line which has either Hello or Goodbye or both on it).

i would have thought grep would have been able to do this, but all i could get it to do was search "Hello " or "Goodbye", not "Hello "and "Goodbye"


Does anybody know a command that will do this for bash?

Does anybody know what im talking about (-:


Cheers!


Lucas

Last edited by ducka; 09-03-2003 at 09:14 AM.
 
Old 09-03-2003, 09:21 AM   #2
Strike
Member
 
Registered: Jun 2001
Location: Houston, TX, USA
Distribution: Debian
Posts: 569

Rep: Reputation: 31
grep "Hello" filename | grep "Goodbye"
 
Old 09-03-2003, 07:06 PM   #3
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Original Poster
Rep: Reputation: 0
cool.. yer that would work..

what if there were multiple instances of the pattern though.. not just 2.

say if a user were to enter 3 serch items in at the command line? and perhaps next time 5, and then 1 etc etc.

i need to write a shells script that will search a file for multiple patterns (that are passed to it through the command line), so i was wondering, if possible, is there a program out there that would take a string of patterns (each separated by a space, or some delimitering character), and then search for each pattern in the string?

if not, i think ill have to rethink my program design (-:


cheers!

Lucas

Last edited by ducka; 09-03-2003 at 07:07 PM.
 
Old 09-03-2003, 08:16 PM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
You can try to use regular expressions and grep: "grep -e" or plain "egrep" but that would get messy and complicated in a hurry.

Or, since you said you're doing this in a shell script, do this (pseudo-code of course):

Code:
if temp_file exists
  remove it

copy file from command line to temp_file

foreach pattern on command-line
begin
  cat temp_file | grep argument > temp_file2
  mv temp_file2 temp_file
end

cat temp_file
 
Old 09-03-2003, 08:28 PM   #5
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Original Poster
Rep: Reputation: 0
Hmm.. looks good.. do u think that it would a reasonably efficent script? will the use of the extra temp files, and the moving of those files suck a bit of time?



cheers!
 
Old 09-03-2003, 09:04 PM   #6
jfshadow
Member
 
Registered: Feb 2002
Location: Amarillo, Texas
Distribution: Slackware 9.1 (desktop) / WinXP w/VMware linux dev/Tawie Server Linux (TSL) 2.0 (servers)/ LFS (dev)
Posts: 47

Rep: Reputation: 15
You can do a lot with awk. Awk would be faster to put together, but I prefer perl, since it runs a lot faster than any of the other utilities.
 
Old 09-03-2003, 09:14 PM   #7
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Original Poster
Rep: Reputation: 0
yer.. unfortunatly in this case i have to stick to pure shell.. (i havent delt with awk, or pearl before, i have heard, and i am asuming they are different languages)
cheers!
 
Old 09-03-2003, 09:21 PM   #8
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Ok, how about this:

Code:
#!/bin/bash

original_filename=<filename argument from command-line>
start_pattern=<first_pattern on command-line>

command_to_exec="grep -e \"$start_pattern\" $original_filename"

if( number of patterns on command-line > 1 )
begin
  foreach remaining arg on command-line
  begin
    command_to_exec="$command_to_exec | grep -e \"$arg\" "
  end
end

$command_to_exec
EDIT:
Added double quotes around the string manipulation... not sure if they're needed though... And removed the stupid command_base variable... not needed in the slightest...

Last edited by Dark_Helmet; 09-03-2003 at 10:40 PM.
 
Old 09-03-2003, 09:38 PM   #9
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Original Poster
Rep: Reputation: 0
hey thats not bad man. id rather pipe the output then store it in a file.. think that should do the trick!

Cheers for that!

Lucas..
 
Old 09-04-2003, 01:08 AM   #10
Strike
Member
 
Registered: Jun 2001
Location: Houston, TX, USA
Distribution: Debian
Posts: 569

Rep: Reputation: 31
Dark_Helmet: I was about to dock you one point for gratuitous piping of cat to grep (since grep takes a filename), but then you fixed it .. so you're in the clear for now

/me leers at Dark_Helmet as he walks out of the room

In fact, it reminds me of an equally embarrassing scene from the movie from which you derive your namesake (I presume) ... "Did you see anything??!!?" "NO! I DIDN'T SEE YOU PLAYING WITH YOUR DOLLS, SIR!!" "GOOD!"
 
Old 09-04-2003, 01:26 AM   #11
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Original Poster
Rep: Reputation: 0
LoLz


ok.. ive tried wring the code that you suggested at the top.. but i cant seem to get it working

if i type in

grep -e $PATTERN1 $FILENAME | grep -e $PATTERN2

into the shell prompt, it works fine.. BUT! as soon as i try store it into a shell variable, for some reason the pipe character ( | ) looses it's meaning??

CMD_TO_EXEC="grep -e $PATTERN1 $FILENAME | grep -e $PATTERN2"

$CMD_TO_EXEC

The above code shows everything that matches the first grep statement (for PATTERN1), but the second one (PATTERN2) is forgoton.. why does this happen?? its making me very sad ) :

lol.. n e way.. if u could help out, and soon.. that would be much appreciated.

cheers!

Lucas

Last edited by ducka; 09-04-2003 at 01:28 AM.
 
Old 09-04-2003, 01:49 AM   #12
ducka
LQ Newbie
 
Registered: Sep 2003
Location: Australia, QLD
Posts: 13

Original Poster
Rep: Reputation: 0
Nevermind



nevermind

i discovered the usage of "eval"

thanks for all your help..

Cheers!

Lucas da
 
Old 09-04-2003, 09:34 AM   #13
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Not to hijack the thread, but YES! Dark Helmet is my personal hero. Powerful. confident, and very focused on appearance. I mean, can you really be a menacing presence without an appropriate tie??

"Yogurt! I HATE Yogurt! Even with strawberries..."
 
Old 09-04-2003, 11:30 AM   #14
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
If you don't need to search using real regular expressions, but only litteral strings, you could try this pure bash script. No grep, no temp files. Not as fast as "grep ... | grep ... | grep ..." though..

Give as many strings you like as arguments on the command line for this script, and it will print only the lines of the file "data.txt" containing all the strings given on the command line.
Code:
#!/bin/bash

FILE=data.txt

cat $FILE | while read LINE ; do
        match=1
        for WORD in $* ; do
                tmp=${LINE%%${WORD}*}
                if [ "${#LINE}" == "${#tmp}" ] ; then
                        match=0
                        break
                fi
        done
        test "$match" == "1" && echo "$LINE"
done

Last edited by Hko; 09-04-2003 at 11:46 AM.
 
Old 09-04-2003, 02:20 PM   #15
J_Szucs
Senior Member
 
Registered: Nov 2001
Location: Budapest, Hungary
Distribution: SuSE 6.4-11.3, Dsl linux, FreeBSD 4.3-6.2, Mandrake 8.2, Redhat, UHU, Debian Etch
Posts: 1,126

Rep: Reputation: 58
How about this one (it is basically one line):

searchfile=$1
searchphrase=$2
eval "cat $searchfile | grep "`echo $searchphrase | sed 's/ / \| grep /g'`

If you name the script as "showlines", use it like this:
./showlines 'filetobesearched' 'search phrase'

(note that the parameters must be quoted)

Naturally, 'filetobesearched' may denote multiple files, like '*.htm', and there can be any number of words in 'search phrase' (there will be as many grep commands executed in a chain as many words there are in the search phrase)
The weakness of the script: in its present state there should be no leading or trailing spaces in the search phrase, and the words in the search phrase should be separated by exactly one space or an error occurs. However, it seems to work fine with these restrictions.

Last edited by J_Szucs; 09-04-2003 at 02:52 PM.
 
  


Reply



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 Syslog - email shell script voodoofxz Linux - Newbie 1 09-06-2005 04:27 PM
grep in shell script fails on redhat 3.0 rlangsto Linux - General 4 03-06-2005 07:42 PM
[c shell] using grep saiz66 Programming 6 09-30-2004 01:45 PM
Shell grep issue philipz Programming 8 05-05-2004 01:50 PM
line addressing with grep (shell scripting) j2dizzo Linux - General 13 03-03-2004 09:36 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:55 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration