hawarden_
hawarden_

Reputation: 2160

sed : how to print all lines after line with a match?

I got my research result after using sed :

zcat file* | sed -e 's/.*text=\(.*\)status=[^/]*/\1/' | cut -f 1 - | grep "pattern"

But it only shows the part that I cut. How can I print all lines after a match ?

I'm using zcat so I cannot use awk.

Thanks.

Edited :

This is my log file :

[01/09/2015 00:00:47]       INFO=54646486432154646 from=steve   idfrom=55516654455457       to=jone       idto=5552045646464 guid=100021623456461451463   n
um=6    text=hi my number is 0 811 22 1/12   status=new      survstatus=new

My aim is to find all users that spam my site with their telephone numbers (using grep "pattern") then print all the lines to get all the information about each spam. The problem is there may be matches in INFO or id, so I use sed to get the text first.

Upvotes: 41

Views: 71296

Answers (6)

Stuart Lynne
Stuart Lynne

Reputation: 111

The seldom used branch command will do this for you. Until you match, use n for next then branch to beginning. After match, use n to skip the matching line, then a loop copying the remaining lines.

cat file \
| sed -n -e ':start; /pattern/b match;n; b start; :match n; :copy; p; n ; b copy'

Upvotes: 3

JB.
JB.

Reputation: 42114

To print all lines after, and including, the first match:

$ echo -ne 'apple\nbanana\ncherry\n' | sed -ne '/banana/,$ p'
banana
cherry

To print all lines after, and NOT including, the first match:

$ echo -ne 'apple\nbanana\ncherry\n' | sed -e '1,/banana/ d'
cherry

Filtering lines when pattern matches between "text=" and "status=" can be done with a simple grep, no need for sed and cut:

$ grep 'text=.*pattern.* status='

Upvotes: 99

Alain
Alain

Reputation: 1

By simply using : grep -A$numberoflines "Word" file If you dont know the numberoflines use wc -l

Upvotes: 0

karakfa
karakfa

Reputation: 67507

You can use awk

awk '/pattern/,EOF'

n.b. don't be fooled: EOF is just an uninitialized variable, and by default 0 (false). So that condition cannot be satisfied until the end of file.

Perhaps this could be combined with all the previous answers using awk as well.

Upvotes: 21

tripleee
tripleee

Reputation: 189457

Maybe this is what you actually want? Find lines matching "pattern" and extract the field after text= up through just before status=?

zcat file* | sed -e '/pattern/s/.*text=\(.*\)status=[^/]*/\1/'

You are not revealing what pattern actually is -- if it's a variable, you cannot use single quotes around it.

Notice that \(.*\)status=[^/]* would match up through survstatus=new in your example. That is probably not what you want? There doesn't seem to be a status= followed by a slash anywhere -- you really should explain in more detail what you are actually trying to accomplish.

Your question title says "all line after a match" so perhaps you want everything after text=? Then that's simply

sed 's/.*text=//'

i.e. replace up through text= with nothing, and keep the rest. (I trust you can figure out how to change the surrounding script into zcat file* | sed '/pattern/s/.*text=//' ... oops, maybe my trust failed.)

Upvotes: 5

Elbert Hannah
Elbert Hannah

Reputation: 1

zcat file* | sed -e 's/.*text=\(.*\)status=[^/]*/\1/' | ***cut -f 1 - | grep "pattern"***

instead change the last 2 segments of your pipeline so that:

zcat file* | sed -e 's/.*text=\(.*\)status=[^/]*/\1/' | **awk '$1 ~ "pattern" {print $0}'**

Upvotes: 0

Related Questions