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 04-16-2013, 10:45 AM   #1
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Rep: Reputation: 17
SED, or GREP Command


I need to search for a string (string1) in a file, but that sting has a few lines that need to go with it. The problem is that the number of lines vary. so I need to search for word in a file and find all of the other connecting lines with it. See below for example
(empty line)
/tmp
bad line
bad line
bad line
bad line
(empty line)
/tmp
good line
good line
good line
String1
good line
good line
good line
(empty line)
/tmp
bad line
bad line
bad line
bad line
(empty line)

now I want to search for string1 and get all of the good lines that are with it. All good lines start with "tmp" and it always ends in an empty line. So I need ONLY everything in between, and including, the "tmp" and the (empty line) that is associated with "string1"

I know sed can do this very easily I just am not sure of the syntax.

Any help would be great.

Thanks

Last edited by edwardcode; 04-16-2013 at 11:04 AM.
 
Old 04-16-2013, 10:57 AM   #2
cortman
Member
 
Registered: Jan 2012
Location: ZZ9 Plural Z Alpha
Distribution: Crunchbang 11, LFS 7.3, DSL 4.1.10, Lubuntu 12.10, Debian 7
Posts: 219

Rep: Reputation: 43
If I understand correctly, you want to get all the text between /tmp and [empty line] if a certain string is contained between the two?
I'm a base beginner at sed too, but perhaps this would work-

Code:
sed -n '/\/tmp/,/^$/p' file_name

Last edited by cortman; 04-16-2013 at 12:55 PM.
 
Old 04-16-2013, 11:03 AM   #3
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Original Poster
Rep: Reputation: 17
I tried that but that dose not search for string1. Also all of the lines start with /tmp so that would bring up the entire file.


P.S. The proper syntax for the command you want to run is:

sed -n '/\/tmp/,/^$/p' file_name

You need a coma not a period.

Last edited by edwardcode; 04-16-2013 at 11:05 AM.
 
Old 04-16-2013, 11:03 AM   #4
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
With this InFile ...
Code:
bad line 1
bad line 2
bad line 3
bad line 4

/tmp
good line 1
good line 2
good line 3
String1
good line 4
good line 5
good line 6

bad line 5
bad line 6
bad line 7

bad line 1
bad line 2
bad line 3
bad line 4

/tmp
good line 11
good line 12
good line 13
String2
good line 14
good line 15
good line 16

bad line 15
bad line 16
bad line 17
... this code ..
Code:
sed -n '/\/tmp/,/^$/p' $InFile >$OutFile
... produced this OutFile ...
Code:
/tmp
good line 1
good line 2
good line 3
String1
good line 4
good line 5
good line 6

/tmp
good line 11
good line 12
good line 13
String2
good line 14
good line 15
good line 16
Daniel B. Martin
 
Old 04-16-2013, 11:06 AM   #5
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by edwardcode View Post
I tried that but that dose not search for string1.
You provided a sample input file. It is also helpful if you provide a corresponding sample output file. This helps us understand your description of the desired result.

Daniel B. Martin
 
Old 04-16-2013, 11:07 AM   #6
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Original Poster
Rep: Reputation: 17
I did make a small change the original post. All "sections" start with /tmp. So I need to search for string and get all lines that go upto /tmp and down to the empty line.
 
Old 04-16-2013, 11:08 AM   #7
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Original Poster
Rep: Reputation: 17
See below for the sample input and the sample output for the search I need to do. Remember the number of lines before and after the string may vary. The only thing that seems to be consistent is the /tmp on top and the empty line on the bottom of string1.


Sample input:


(empty line)
/tmp
bad line
bad line
bad line
bad line
(empty line)
/tmp
good line
good line
good line
String1
good line
good line
good line
(empty line)
/tmp
bad line
bad line
bad line
bad line
(empty line)



Sample output:

/tmp
good line
good line
good line
String1
good line
good line
good line
(empty line)

Last edited by edwardcode; 04-16-2013 at 11:16 AM.
 
Old 04-16-2013, 11:22 AM   #8
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Proposed solution withdrawn. Haste makes waste!

Last edited by danielbmartin; 04-16-2013 at 11:25 AM. Reason: Rescind post
 
Old 04-16-2013, 11:29 AM   #9
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Original Poster
Rep: Reputation: 17
That output bad lines I need nothing but the block of good lines. Maybe I am using the wrong command for this. I am fairly certain that there is a way to do it with regex. I also thought you could do it with sed but the more I research it the more trouble I am getting.
 
Old 04-16-2013, 11:36 AM   #10
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
You are looking for a "grep with context" where the context is defined by something other than a fixed number of lines before and/or after a string match.

With this InFile ...
Code:
bad line 1
bad line 2
bad line 3
bad line 4

/tmp
good line 1
good line 2
good line 3
String1
good line 4
good line 5
good line 6

bad line 5
bad line 6
bad line 7

bad line 1
bad line 2
bad line 3
bad line 4

/tmp
good line 11
good line 12
good line 13
String2
good line 14
good line 15
good line 16

bad line 15
bad line 16
bad line 17
... this code ..
Code:
paste -d"~" -s $InFile       \
|sed 's/~\/tmp/\n\/tmp/g'    \
|grep ^/tmp                  \
|grep String2                \
|sed -r 's/(.*)(~~.*)/\1~/g' \
|sed 's/~/\n/g'              \
> $OutFile
... produced this OutFile ...
Code:
/tmp
good line 11
good line 12
good line 13
String2
good line 14
good line 15
good line 16
Daniel B. Martin

Last edited by danielbmartin; 04-16-2013 at 11:45 AM. Reason: Minor code improvement
 
Old 04-16-2013, 11:53 AM   #11
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Original Poster
Rep: Reputation: 17
The only problem I have with that set up is that this will be applied on gig's and gig's of text files and I would rather just have one command (even if it is regex) that would be able to parse it. I also think that awk might be able to work, but I am still not sure.
 
Old 04-16-2013, 11:57 AM   #12
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Hi, what about
Code:
sed -n '/\/tmp/,/^$/H; /^$/{x; /String1/p}' <infile
 
1 members found this post helpful.
Old 04-16-2013, 12:00 PM   #13
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by edwardcode View Post
The only problem I have with that set up is that this will be applied on gig's and gig's of text files and I would rather just have one command (even if it is regex) that would be able to parse it. I also think that awk might be able to work, but I am still not sure.
Don't discard a solution before trying it.

A single complicated awk might not be any better than a pipe of several simpler transformations.

Daniel B. Martin
 
Old 04-16-2013, 12:05 PM   #14
edwardcode
Member
 
Registered: Apr 2010
Posts: 161

Original Poster
Rep: Reputation: 17
Milgates,
That was what I was looking for. Will you please explain this portion of your code:

/^$/{x; /String1/p}'

Thanks
 
Old 04-16-2013, 12:16 PM   #15
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
millgates beat me to it. Mine is something more complicated.
Code:
sed -n -e '/\/tmp/,/^$/{ /tmp/{ h; b; }; H; /String1/,/^$/{ /^$/{ x; p; }; }; }'
 
  


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
[SOLVED] Need a particular sed / grep command to solve problem khandu Programming 6 11-18-2012 03:34 AM
Using Grep/Awk/Sed to get a substring from a command johnjust Programming 5 01-12-2010 08:02 PM
Grep or Sed ? How can I use it ? ArOnaXx Linux - Newbie 6 04-12-2009 02:08 PM
how to use grep/sed tnik Linux - General 3 11-06-2007 07:51 PM
bash script with grep and sed: sed getting filenames from grep odysseus.lost Programming 1 07-17-2006 11:36 AM

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

All times are GMT -5. The time now is 10:11 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