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.

grep --before-context 5 shows 5 lines before the match.

I want to show everything before the match.
Doing grep --before-context 99999999 would work but it is not very... professional.

How to show all the file up to the match?

share|improve this question

5 Answers 5

up vote 20 down vote accepted

Sed is better for that.

Just do:

sed '/PATTERN/q' FILE

It works like this:

For each line, we look if it matches /PATTERN:

  • if yes, we print it and quit
  • otherwise, we print it

This is the most efficient solution, because as soon as it sees PATTERN, it quits. Without q, sed would continue to read the rest of the file, and do nothing with it. For big files it can make a difference.

This trick can also be used to emulate head:

sed 10q FILE
share|improve this answer
    
Just tried, it just outputs the first line of the file... even though match is at line 38. –  Nicolas Raoul Apr 14 '11 at 9:44
    
Works fine for me. Can you give an example of actual input and output? And the command you are running as-is. –  Mikel Apr 14 '11 at 9:46
    
I had tried your command before you edited it, it was: sed '/PATTERN/p;q' FILE –  Nicolas Raoul Apr 14 '11 at 9:51

sed can replace most of grep's functionality.

sed -n '1,/<pattern>/ p' <file>

This means print from the first line until pattern is matched.

A couple of range examples

sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2
share|improve this answer
    
Thanks it works! –  Nicolas Raoul Apr 14 '11 at 9:49
2  
This command is good, but you can do better. This way it reads the whole file, but it is possible to quit as soon as it has found a match. –  Mikel Apr 14 '11 at 9:55

print up to and including the match:

awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename

print up to BUT NOT including the match:

awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
share|improve this answer
2  
Q's cool but gnu specific afaik, sed -n '/pattern/!p;//q' would be more portable. –  don_crissti Apr 6 at 13:36

For people like me, who choose to remember only the basic usage of tools, and willing to accept less elegant and less efficient solutions:

head -n $(grep -n pattern filename | cut -d: -f1) filename
share|improve this answer
1  
Nice idea, but three commands when one will do. –  Mikel Apr 14 '11 at 9:47
    
Knowing the basics is very good indeed. Knowing the right tool for the job is better, though. –  soulmerge Apr 14 '11 at 15:00
    
If this command is for a script then I will look for more elegant (and possibly efficient) solutions. If this is a one time command (or a throw away script), then I don't care. –  lesmana Apr 14 '11 at 17:59

You could also use one of the following

tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

or

tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac

or

tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac

The first option is very similar to what the OP suggested only it makes sure ti show enough lines before context by counting the lines in the file

The second option searches the line number of the first match (you could change that as well by changing the inner 'head') and than uses head on that number

The last option replaces all new lines with the match and than replaces two adjacent matches with a new line. The output of this is a line for every block of text between two matches. After that it uses 'head' to choose the first line (mwaning the block of text until the first match) match and than retranslates each match to a new line. this option works only if the file is in the following format

pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern 
texttexttext
texttexttexttexttexttexttexttexttext

and so forth

share|improve this answer
1  
consider explaining how these work, especially because that sed command at the bottom is kind of gnarly. –  strugee Jul 9 at 19:45
    
the first option is very similar to what the OP suggested only it makes sure ti show enough kines before context by counting the lines in the filr, –  user122778 Jul 10 at 5:49

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.