Operating System - HP-UX
1827770 Members
2720 Online
109969 Solutions
New Discussion

perl or awk command to print next line after pattern in txt file ??

 
SOLVED
Go to solution
Sammy_2
Super Advisor

perl or awk command to print next line after pattern in txt file ??

The log file has the pattern "error" in one line but next line gives the actual error explanation in a text file.
How do I grep/print the next line after a pattern ?

With perl, I only go this far but needs to know what comes in between double quotes after perl -e.
Or , I am open to other awk/sed suggestions.
Thx



cat file | perl -e " "; while (<>) {print if /error/ }"
good judgement comes from experience and experience comes from bad judgement.
17 REPLIES 17
James R. Ferguson
Acclaimed Contributor
Solution

Re: perl or awk command to print next line after pattern in txt file ??

Hi Sammy:

One way:

# perl -nle 'if (/error/i && !eof) {chomp($line=<>);print "$_\n$line"}' file

Regards!

...JRF...
Sammy_2
Super Advisor

Re: perl or awk command to print next line after pattern in txt file ??

JRF,
Bingo !! Thx
That is what I need. i got a equivalent awk command but I like PERl.
10 pointer answer. Now, I need to figure out where you store the lines by cracking this oreilly perl book.


awk '/error/{print;for(i=0;i<1;i++){getline;print}}' file
good judgement comes from experience and experience comes from bad judgement.
Dennis Handly
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

Gnu grep has a -A1 option:
grep -A1 error file ...

For sed:
sed -n '/error/ { p; n; p; }' file ...
Sammy_2
Super Advisor

Re: perl or awk command to print next line after pattern in txt file ??

Dennis,
I get exactly what I want. But please help me out here.

When i substitute error for a variable $ERROR and set $ERROR=error, I dont get same result.

I am having same issues with JRF solution. I have put double quotes, single quote but dont get same thing.



Thx
good judgement comes from experience and experience comes from bad judgement.
Dennis Handly
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

>When I substitute error for a variable $ERROR and set $ERROR=error, I don't get same result.

Because everything is in '' which says don't evaluate $ variables. I typically use single quotes just so I won't get incorrect evaluation. For your three cases:
sed -n "/$ERROR/ { p; n; p; }" file ...
perl -nle "if (/$ERROR/i && !eof) {chomp(\$line=<>); print \"\$_\n\$line\"}" file

Note the quoting of the other "$" and double quotes.
You could also stutter quotes:
perl -nle 'if (/'"$ERROR"'/i && !eof) {chomp($line=<>); print "$_\n$line"}' file

For awk, don't play that game, use -v to pass them:
awk -v string="$ERROR" '$0 ~ string {print; for(i=0;i<1;i++){getline; print}}' file
H.Merijn Brand (procura
Honored Contributor

Re: perl or awk command to print next line after pattern in txt file ??

$ perl -ne'/error/i...($.+1) and print' file

Just because I couldn't resist to show a shorter version. Also safe at eof.

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
H.Merijn Brand (procura
Honored Contributor

Re: perl or awk command to print next line after pattern in txt file ??

if $ERROR is in your environment, don't play silly games with quotes, but use the environment itself!

$ perl -ne'/$ENV{ERROR}/i...($.+1) and print' file

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
James R. Ferguson
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

Hi (again):

For clarity, I should have eliminated the needless addition ('-l') and subtraction ('chomp') of newlines in my original suggestion, reducing it to:

# perl -ne 'if (/error/i && !eof) {$line=<>;print $_,$line}' file

However, Merijn's solution is by far better golf and much more Perl DWIM :-)

With 'awk' as Dennis noted, rather than fiddling around escaping the shell special characters, one generally passes environmental variables with the '-v' construct.

In Perl, leveraging the 'ENV' hash pays dividends as Merijn stated. You can do this too in 'awk'. As a simple example, compare:

# export MYVAR=ERROR
# echo "ERROR\nerror\nError"|awk '{if (tolower($0)~tolower(ENVIRON["MYVAR"])) {print}}'

# export MYVAR=ERROR
# echo "ERROR\nerror\nError"|perl -ne '/$ENV{MYVAR}/i and print'


Regards!

...JRF...

Sammy_2
Super Advisor

Re: perl or awk command to print next line after pattern in txt file ??

First of all Dennis , Thanks a bunch .
Your modification of JRF perl works beautifully. sed does too.

Much thanks to Procura and JRF again.

Procura, As JRF agreed, your shorter version is better and I would like to use that.

However, I get different results, when I am trying to grep on pattern , for instance . "Mar 16" from a file when I used the ENV variable as mentioned below.(Please see below). If i hard code "Mar 16", I get right results.
What am I doing wroing ???
BIG THANKS to ALL OF YOU . I 've learned a lot.



# perl -ne'/Mar 16/i...($.+1) and print' file
Mar 16 11:48:06 2009 : kevi137 : TTY=pts/3 ; PWD=/export/home/kevi137 ;
USER=root ; COMMAND=/usr/local/bin/su_tibco
Mar 16 15:48:44 2010 : chri119 : command not allowed ; TTY=pts/1 ;
PWD=/export/home/chri119 ; USER=root ; COMMAND=/usr/local/bin/su_tibcoadm /app/tibco/pmcrefresh/test
Mar 16 15:51:56 2010 : chri119 : TTY=pts/7 ; PWD=/export/home/chri119 ;
USER=root ; COMMAND=/app/tibco/pmcrefresh/test
Mar 16 15:53:45 2010 : chri119 : TTY=pts/7 ; PWD=/app/tibco/pmcrefresh ;
USER=root ; COMMAND=/app/tibco/pmcrefresh/test.sh



# echo $ERROR
Mar 16
# perl -ne'/$ENV{ERROR}/i...($.+1) and print' file


Sep 21 08:09:14 2007 : wesle15 : user NOT authorized on host ; TTY=pts/1 ;
PWD=/export/home/wesle15 ; USER=root ; COMMAND=su_tibco
Sep 21 08:29:43 2007 : wesle15 : 1 incorrect password attempt ; TTY=pts/2 ;
PWD=/export/home/wesle15 ; USER=root ; COMMAND=su_tibco
Sep 21 08:53:20 2007 : wesle15 : user NOT authorized on host ; TTY=pts/1 ;
PWD=/export/home/wesle15 ; USER=root ; COMMAND=su_tibco
Sep 21 08:57:01 2007 : wesle15 : command not allowed ; TTY=pts/8 ;
PWD=/export/home/wesle15 ; USER=root ; COMMAND=su_tibco
Sep 21 08:59:26 2007 : nichol5 : command not allowed ; TTY=pts/1 ; PWD=/ ;
USER=root ; COMMAND=su_tibco
Sep 21 09:00:25 2007 : nichol5 : TTY=pts/1 ; PWD=/ ; USER=root ; COMMAND=/usr/lo
cal/bin/su_tibco
Sep 21 09:01:01 2007 : wesle15 : TTY=pts/8 ; PWD=/export/home/wesle15 ;
USER=root ; COMMAND=/usr/local/bin/su_tibco
Sep 21 09:36:09 2007 : harin01 : TTY=pts/9 ; PWD=/export/home/harin01 ;
USER=root ; COMMAND=/usr/local/bin/su_tibco

good judgement comes from experience and experience comes from bad judgement.
James R. Ferguson
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

Hi Sammy:

> However, I get different results, when I am trying to grep on pattern , for instance . "Mar 16" from a file when I used the ENV variable as mentioned below.(Please see below). If i hard code "Mar 16", I get right results.

This would be true if your environmental variable weren't defined. While I accept what you say, Verify what Perl sees by adding the warnings pragma:

# # perl -wne'/$ENV{ERROR}/i...($.+1) and print' file

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

># echo $ERROR

As JRF asked, have you exported ERROR?
env | grep ERROR
James R. Ferguson
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

Hi (again) Sammy:

In fact, perhaps you meant to export the variable for the duration of the command line but added a semicolon instead:

# ERROR="Mar 16" perl -wne'/$ENV{ERROR}/i...($.+1) and print' file

...works, but this does not:

# ERROR="Mar 16";perl -wne'/$ENV{ERROR}/i...($.+1) and print' file

Too, in the second case:

# echo $ERROR

...would look like the variable were defined (and maybe exported), *but* as Dennis also suggested, 'env|grep ERROR' would not return anything.

Regards!

...JRF...
Sammy_2
Super Advisor

Re: perl or awk command to print next line after pattern in txt file ??

Once again, thanks, JRF and Dennis.

"Brain lock error" on my behalf. I must have not exported the variable. All good and veery, very thx to help me jog my rusty perl brain.
good judgement comes from experience and experience comes from bad judgement.
Bob E Campbell
Honored Contributor

Re: perl or awk command to print next line after pattern in txt file ??

just to prove everything can be done in shell...

grep -e error -n file |\
while read data
do
line=${data%%:*}
eval head "-$(( $line + 1 )) foo" | tail -1
done

Yes, this assumes that error is not on the last line of the file...
H.Merijn Brand (procura
Honored Contributor

Re: perl or awk command to print next line after pattern in txt file ??

Your perl brain isn't rusty. I bet a lot of readers didn't use the triple-dot operator in the past weeks, months, days :) It's advanced perl, and you just happened to come up with a problem where it is perfectly used for.

As a side note, in your original post you do

$ cat file | perl -e'......'

which is one process too many.
Both

$ perl -e'....' file

and

$ perl -e'....' < file

would be more effective. Sorry I want to say it, but it is a pet-peeve of mine. Don't waste process slots.

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Sagar Sirdesai
Trusted Contributor

Re: perl or awk command to print next line after pattern in txt file ??

You can use sed to achieve this

Create sed file as below and assume the pattern is root

/root/
{
n
p
}

Then run the sed command as

sed -n -f sed.file
Dennis Handly
Acclaimed Contributor

Re: perl or awk command to print next line after pattern in txt file ??

>Sagar: You can use sed to achieve this: { n; p; }

It appears you aren't printing the line you match but only the next one.