1848362 Members
6682 Online
104024 Solutions
New Discussion

Re: Perl grep question

 
SOLVED
Go to solution
Jason Berendsen
Regular Advisor

Perl grep question

I need to pull blocks of information from a log if the block meets a condition.

The log is set up as follows:
Account Name:
User Name:
Date:
Time:
Description:

I want to be able to pull all blocks that have an account name like Unix. Is there a way in perl to say find a line with Account Name = Unix and give me all other information until the next blank line?
11 REPLIES 11
Marvin Strong
Honored Contributor
Solution

Re: Perl grep question

probably a better way, but I would do something like this.

open F, "<$ARGV[0]" or die "$!";
while () {
if (/^$/) {
$go_on="";
next;
}
if (/Account Name/) {
($label, $data)=split/:/;
if ($data =~ /Unix/) {
$go_on = 1;
}
}
print if $go_on;
}
close F;


Rodney Hills
Honored Contributor

Re: Perl grep question

perl -ne 'print if /^Account Name: Unix/../^$/'

HTH

-- Rod Hills
There be dragons...
Marvin Strong
Honored Contributor

Re: Perl grep question

nice one liner. Rodney
Hein van den Heuvel
Honored Contributor

Re: Perl grep question

Nice one liner indeed.

Now if you need to do more than just the print, then yo may want to consider the more classical 'set flag when in range' approach:

perl -ne '$block=1 if (/^Account Name: Unix/); print if ($block); $block=0 if (/^$/); ' < your-file>

flip the print and block=0 sub commands depending on whether you want to retain the empty line or not.

fwiw,
Hein.
Jason Berendsen
Regular Advisor

Re: Perl grep question

Thanks for each of the responses, I'm sure each way works fine. But, due to my inexperience with Perl I am having trouble with the one liners. Let me show you my test input file called /tmp/log.tmp:

Account Name: schmoe
User Name: Joe Schmoe
Date: 04/14/2004
Time: 10:10
Description: Test

Account Name: doej
User Name: John Doe
Date: 04/14/2004
Time: 10:10
Description: Test

I try the following one liner and get a blank line for a return:

perl -ne 'print if /^Account Name: Unix/./^$/' /tmp/log.tmp

I then try the other one liner and get 00000 for a return:

perl -ne '$block=1 if(/^Account Name: Unix/); print ($block); $block=0 if (/^$/);' /tmp/log.tmp


I am sure I am making a very dumb mistake but as of yet I can't find it. Is my syntax wrong????
Pete Randall
Outstanding Contributor

Re: Perl grep question

Jason,

How about a sed solution:

# print paragraph if it contains AAA (blank lines separate paragraphs)
# HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'


From "Handy One-Liners for Sed" (attached).


Pete

Pete
A. Clay Stephenson
Acclaimed Contributor

Re: Perl grep question

Well, the obvious problem is that your Perl script is looking for "Account Name: Unix" but there is no such entry in your test file.

Also because the Forum's HTML code (any HTML for that matter) doesn't handle whitespace well, make sure that the expected string exactly matches the input.
If it ain't broke, I can fix that.
Marvin Strong
Honored Contributor

Re: Perl grep question

All of the perl. Is looking for the word Unix. However now I see you want unix like usernames.

That changes the expression that is needed in order for the patterns to match.

An actual data sample, of one that should match and one that should not match, would help.


Jason Berendsen
Regular Advisor

Re: Perl grep question

I obviously wasn't paying attention when I put Unix in. I would like to use SED but I need this script to be portable to the Wintel environment with little modification. In my earlier example file is there a way to pull the whole paragraph associated with the line User: Joe Schmoe? I need all the information associated with this name.
Jason Berendsen
Regular Advisor

Re: Perl grep question

I was able to figure it out using Rodney's and Hein's one liner. Thanks for all the help.
Scott Palmer_1
Trusted Contributor

Re: Perl grep question

open (INFILE,"while() {
chomp;
if (/AccountName:\s+Unix/ ... /Description:/) {
print "$_\n";
}
}

forgive the spacing problem but the if statement should be on the same line.
Hopefully this is what you are looking for

Regards,
Scott Palmer