Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Below is the text in the file:

Pseudo name=Apple
Code=42B
state=fault

Pseudo name=Prance
Code=43B
state=good

I need to grep for "42B" and get the output from the above text like:

Pseudo name=Apple
Code=42B
state=fault

Does anyone have idea on how to achieve this using grep/awk/sed?

share|improve this question
    
You tagged this question with just "grep". Are you only looking for "grep" solutions then? In the question you specify awk & sed too. Can we add those tags? I wasn't sure of your intent when I edited the question last night. –  slm Jul 14 '13 at 12:06

3 Answers 3

With awk

awk -v RS='' '/42B/' file

Change the record separator from \n to blank lines. If any field in an record contains /42B/ print the record.

share|improve this answer
1  
+1 for an elegant solution. You don't need to redirect the file though... –  jasonwryan Jul 14 '13 at 3:53
    
fingers were on autopilot. –  arx Jul 14 '13 at 14:16

Assuming the data is structured so that it's always the line before and after that you want you can make use of grep's -A (after) and -B (before) switches to tell it to include the 1 line before the match and 1 line after it:

$ grep -A 1 -B 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault

If you want the same number lines before and after the search term you can use the -C (context) switch:

$ grep -C 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault

If you'd like to be more stringent when matching the multiple lines you can use the tool pcregrep, to match a pattern over multiple lines:

$ pcregrep -M 'Pseudo.*\n.*42B.*\nstate.*' sample.txt
Pseudo name=Apple
Code=42B
state=fault

The above pattern matches as follows:

  • -M - multiple lines
  • 'Pseudo.*\n.*42B.*\nstate.*' - matches a group of strings where the first string starts with the word "Pseudo" followed by any characters up until a end of line \n, followed by any characters up until the string "42B" followed by any characters up until another end of line (\n), followed by the string "state"followed by any characters.
share|improve this answer
4  
-C (context) can be used as a shortcut, if -A and -B are the same. –  David Baggerman Jul 14 '13 at 0:37
    
@DavidBaggerman - thanks. Added it to the answer. –  slm Jul 14 '13 at 0:39
    
Why the one down vote? This answers the question. –  slm Jul 14 '13 at 12:07

There is probably a similarly easy way to do it with awk, but in perl:

cat file | perl -ne 'BEGIN { $/="\n\n" }; print if $_ =~ /42B/;'

That basically says to split the file into chunks delimited by blank lines, then to only print those chunks that match your regular expression.

share|improve this answer
3  
This can be simplified by using options and shorthands, and losing the useless use of cat; perl -00 -ne 'print if /42B/' file –  tripleee Jul 14 '13 at 7:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.