1820390 Members
3467 Online
109623 Solutions
New Discussion юеВ

Help in Grep/ VI

 
SOLVED
Go to solution
Din_1
Frequent Advisor

Help in Grep/ VI

Hi All,

I have a 100MB text file in my HP UX server. It's a log file for license usage. I need to grep today's license usage and need to be sent to me in the EOD.

Problem is the date appears in the log file as Jul 17 2009, and i need to copy a single line above its appearance and 3 lines below this appearance.

The files looks similar to this format

User : ccxc 1.00License
Group :xxx In-Use Since: Jun 29 2006 09:57:57
Node : xxxx.xxx.com Serial Number:
Acid: Capacity Type: None

( This is a sample of single user usgae detail. Like this lot of appearances are there in the file. )

Since the date appears in the middle of this, i need to get all the four lines in my mail.

Please help me in this

Thanks in Advance,
Din
20 REPLIES 20
Steven E. Protter
Exalted Contributor

Re: Help in Grep/ VI

Shalom,

grep User logfile > license.txt
grep Group logfile >> license.txt
grep Node logfile >> license.txt
grep Acid logfile >> license.txt

You may need to refine the statement or create a temporary file with tail, but this is the basic approach I would use.

I'm sure you could process the file with awk as well.

SEP
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi Din:

# cat .findit
#!/usr/bin/perl
use strict;
use warnings;
my $target = shift or die;
my ( $prev, $n ) = ( '', 0 );
while (<>) {
if (/$target/) {
print $prev, $_;
$n=3;
}
elsif ($n > 0) {
$n--;
print;
}
$prev = $_;
}
1;

...run as:

# ./findit pattern file

# ./findit "Jul 17" file

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi (again) Din:

If you have a GNU version of 'grep' installed, you could do:

# grep -A3 -B1 "Jul 17" file

...where '-A' stands for "lines after" and '-B' stands for "lines before".

Regards!

...JRF...
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Thanks for your replies,

I don't have GNU grep installed on my HP UX server.

Thanks,
Din
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Hi Steven,

If i try as you said, i will get the output, but it will not be in the right format. I need the format as it's available in the log file.

Like a set of sections arrange in the log file.

Thanks in advance,
Din
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi (again) Din:

Since you don't have GNU 'grep' and you don't seem to like Perl, how about 'awk':

# cat ./showit
#!/usr/bin/awk -f
BEGIN{prev=""; n=0; seen=0};
{if ($0~target) {
printf "%s\n%s\n", prev, $0;
seen=1;
n=3;
}
if (n > 0 && seen < 1) {
n--;
printf "%s\n", $0;
}
prev = $0;
seen = 0;
}

...run as:

# ./showit -v target="Jul 17" file

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor
Solution

Re: Help in Grep/ VI

>but it will not be in the right format. I need the format as it's available in the log file.

>Steven: grep User logfile > license.txt
grep Group logfile >> license.txt
grep Node logfile >> license.txt
grep Acid logfile >> license.txt

Instead of using 4 greps, you can do them all at once and the lines will be in order:
grep -e "^User:" -e "^Group:" -e "^Node:" -e "^Acid:" logfile > license.txt

But that will find more than your one date.
Arturo Galbiati
Esteemed Contributor

Re: Help in Grep/ VI

Hi Din,
sed -n '/User :/,/Acid: /p'

This prints from line containing User: (included0 to line containg Acid: (included)

HTH,
Art
Din_1
Frequent Advisor

Re: Help in Grep/ VI

ok, Let me broaden my question. I need to take out the content between Jul 17 2009's first appearance and Jul 17 2009's last appearance.

How can i do this...?

Thanks in Advance,
Din
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi (again) Din:

> I need to take out the content between Jul 17 2009's first appearance and Jul 17 2009's last appearance.

# perl -e 'while (<>) {print if /Jul 17/.../Jul 17/}'

...will provide the content. If it occurs multiple times you will see that too. Is that what you want, or do you _only_ want the first stanza that meets the criteria?

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi Din:

...and of course there is always:

# sed -ne '/Jul 17/,/Jul 17/p' file

Regards!

...JRF...
Gilles Allard
Advisor

Re: Help in Grep/ VI

Here is another approach.
The key would be to have a daily log file.
Let's suppose your log file is licenses.log. Every day, a cron jog would:
- email licenses.log to you
- append licenses.log to licenses.history (your 100MB file)
- erase licenses.log (or empty it)

This approach has the advantage that your script is completely independant of the syntax of the content.
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Hi JRF,

The command that you gave has really worked out, but it's only 80% accurate.

But somehow i managed it by editing manually. Thanks for your inputs.

Regards,
Din
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Is there any possiblity of getting 100% accurate output that i want...

Thanks in advance,
Din
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi (again) Din:

> The command that you gave has really worked out, but it's only 80% accurate. But somehow i managed it by editing manually.

OK.

> Is there any possiblity of getting 100% accurate output that i want...

Yes, but first you need to tell me what "80% accurate" constitutes (by example!). Please provide sample data (as an attachment is best) and the output you want.

Regards!

...JRF...
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Attachment is the output that i have got with the command you gave me. But in this Jul 16 is coming in the middle.

I need that to be excepted in the output. Anyway this is the sample only, like this lot of dates are coming in the middle of the output.

Thanks for your support...
Regards,
Din
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

Hi (again) Din:

I see your output (with the July 16 dates that you don't want) _BUT_ I need both the output _AND_ the input (attached).

In addition to the actual input (as a file), which of the various scripts of mine did you use?

Regards!

...JRF...
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Attachment is the input i gave and output i got

Thanks and Regards,
Din
James R. Ferguson
Acclaimed Contributor

Re: Help in Grep/ VI

HI (again) Din:

OK, you have confused me. Your original question was to find a pattern and list it; the line above it; and three lines below it. I offered a couple of soultions for that.

Then, you changed the question to "I need to take out the content between Jul 17 2009's first appearance and Jul 17 2009's last appearance."

I interpreted that to mean that all you wanted was blocks that looked like:

begin Jul 17
some 17 data
some more 17 data
endof Jul 17
begin Jul 18
some 18 data
some more 18 data
end of Jul 18

...hence I suggested a simple 'sed' where only the blocks beginning and ending with /Jul 17/ were output.

If there is a match on /Jul 17/ but there is never another line with that again, all lines from the first match will be output.

If you want to provide an _actual_ input file (attached) and a second post of the _actual_ output (contrived) from that input, then we can better communicate and find a solution that gives you exactly what you need.

Regards!

...JRF...
Din_1
Frequent Advisor

Re: Help in Grep/ VI

Sorry for the confusion, my earlier requirement was as first question. Actually i forgot to mention my change in requirement to the forum.

My actual requirement is as the last question only...

Sorry for the inconvenience.

Thanks,
Din