Operating System - HP-UX
1820389 Members
3476 Online
109623 Solutions
New Discussion юеВ

perl command line to parse field from a file ??

 
SOLVED
Go to solution
Sammy_2
Super Advisor

perl command line to parse field from a file ??



Using perl commmand below, I am able to successfully parse lines from sudo.log to print lines from todays date ( Today's $DATE variable set as "Jul 2") and one line after todays date (as seen below).

Problem is it is picking up "Jul 2" from 2008 and 2009 as well. How do I modify the perl script below to include only entries from 2010 (in this case just last line). The format is below

Thanks and please help.



# perl -wne'/$ENV{DATE}/i...($.+1) and print' /var/log/sudo.log


Jul 2 09:45:53 2008 : mehmed1 : TTY=pts/3 ; PWD=/export/home/mehmed1 ;
USER=root ; COMMAND=/usr/local/bin/su_flo
Jul 2 10:51:11 2008 : mehmed1 : command not allowed ; TTY=pts/3 ;
PWD=/export/home/mehmed1 ; USER=root ; COMMAND=tibco
Jul 2 10:51:17 2008 : mehmed1 : command not allowed ; TTY=pts/3 ;
PWD=/export/home/mehmed1 ; USER=root ; COMMAND=su_tibco
Jul 2 10:51:24 2009 : mehmed1 : command not allowed ; TTY=pts/3 ;
PWD=/export/home/mehmed1 ; USER=root ; COMMAND=su_tibco
Jul 2 07:31:03 2010 : subir01 : TTY=pts/3 ; PWD=/ ;
USER=root ; COMMAND=/usr/local/bin/su_flo
good judgement comes from experience and experience comes from bad judgement.
9 REPLIES 9
Steven E. Protter
Exalted Contributor

Re: perl command line to parse field from a file ??

Shalom,

If this is a perl scripting project like for a class, it is not appropriate use of these forums.

If you are actually trying to get real world work done, I would not use perl except for fun.

Simple answer:

grep "Jul 2" /var/log/sudo.log | grep 2010 > outputfile.

Not pretty but it gets the job done.

Now it might be fun with awk as well.

ioscan -kfnC fc | awk '/fcd/ {getline;fcd=$NF;print fcd,$2}' | while read -r fdev
do
# fcmsutil ${fdev} | awk '/Hardware / {print $5};/World / { print $7}' | awk ' {printf "%s %s %s %s %s",$1, $2, $3, $4, $5;}'
fcmsutil ${fdev} | awk '/Hardware Path/ {PATH=$5};
/N_Port Node/ {NNODE=$7};
/N_Port Port/ {NPORT=$7};
/Switch Port/ {SPORT=$7};
/Switch Node/ {SNODE=$7};
END{print PATH, NNODE, NPORT, SPORT, SNODE}'
done


Myself and JRF did that yesterday and instead of ioscan, you can cat the sudu log file through, select and parse the output as you wish.

Looks to me like a 10-15 minute modification of the code above.

If you are willing to look an an awk based solution, I will try and write you one.

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
Sammy_2
Super Advisor

Re: perl command line to parse field from a file ??

SEP,
Thanks for responding. This is real deal ( I wish I was young enough for school).
Basically, I am using shell script but put perl command in there since with one command I can in shell scripting terms (grep the date, and print the line after the date). Not sure how easy it is with shell scripting.
I would love for awk based solution if you can provide that.

Thanks


Here is the full script.

#!/usr/bin/ksh
#################################################################

MAILADMIN="sub@abc.com" ; export MAILADMIN
LOG_OUT=/tmp/sudoers.txt ; export LOG_OUT
LOG_OUT2=/tmp/sudoers2.txt ; export LOG_OUT
###++++++++++++
MONTH=`date +"%b`
DAY=`date +"%d`
FIRST_CHAR=`echo $DAY|cut -c1`
if [ $FIRST_CHAR = "0" ];then
DAY=`echo $DAY|tr -s '0' ' '`
DATE="$MONTH $DAY"; export DATE
DATE=`echo $DATE | sed 's/ / &/g'`
echo "$DATE"
else
DATE=`date +"%b %d"`; export DATE
fi

###++++++++++++
good judgement comes from experience and experience comes from bad judgement.
Sammy_2
Super Advisor

Re: perl command line to parse field from a file ??

Sorry, here is the bottom half of the script

perl -wne'/$ENV{DATE}/i...($.+1) and print' /var/log/sudo.log > $LOG_OUT
if [ -s $LOG_OUT ]; then
unix2dos $LOG_OUT > $LOG_OUT2
uuencode $LOG_OUT2 $LOG_OUT2 | mailx -s "Sudo Log on $DATE from Weasel (inbpsdec5)" $MAILADMIN
else
echo " " | mailx -s "NO Sudo Log Entry on $DATE from Weasel (inbpsdec5)" $MAILADMIN
fi
good judgement comes from experience and experience comes from bad judgement.
James R. Ferguson
Acclaimed Contributor
Solution

Re: perl command line to parse field from a file ??

Hi Sammy:

Instead of externally constructing the pattern, let Perl do it all.

# perl -MPOSIX -nle '$re=sprintf strftime "%b %d .{8} %Y",localtime;/$re/...($.+1) and print' /var/log/sudo.log > $LOG_OUT

Regards!

...JRF...
Sammy_2
Super Advisor

Re: perl command line to parse field from a file ??

Thanks JRF.
Due to my lack of Perl knowlege, I am not sure what "localtime" does.
So, I am not sure how your command will grep for string "Jul 2" for today. Sorry.


It seems like your solution may work but my input file has 2spaces after Jul like, "Jul 2" if day is single digit and 1 space after July if "Jul 12". Thus, I using tr command in my script.

I am thinking of just tail -30 /var/log/sudo.log and then run my perl command against it. That way, I know last 30 entries in sudo.log are not from 2009 and 2008. We have abt 5 entries per day in the log. Bad way to do it but mayb serves the purpose.

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

Re: perl command line to parse field from a file ??

Hi (again) Sammy:

To accommodate dates with single-digit days and a leading space, or double-digit days, use this:

# perl -MPOSIX -nle '$re=sprintf strftime "%b %e .{8} %Y",localtime;/$re/...($.+1) and print' /var/log/sudo.log > $LOG_OUT

I erroneously assumed days with leading zeros when I used "%d" in the formatting directive. Change that to '%e' as shown above.

> Due to my lack of Perl knowledge, I am not sure what "localtime" does. So, I am not sure how your command will grep for string "Jul 2" for today. Sorry.

The code simply builds a regular expression to match the current date with an embedded string of 8-characters assumed to be the time. The regular expression looks like: like:

Jul 2 ........ 2010

A dot ('.') matches anything, and hence a time expressed as hh:mm:ss matches around the clock.

The 'localtime' function returns the date/time in *your* timezone, exactly as using 'date' in a shell would do.

Regards!

...JRF...

Hein van den Heuvel
Honored Contributor

Re: perl command line to parse field from a file ??

Hey Sammy, Just a few remarks...

In your starting perl line, you are misleading, and/or have been mis-led.

You use something like: /xxxx/...($.+1)/
This _suggest_ that the +1 gave you the one line after, and it seems to work that way.

But the +1 doesn't do anything you expect.
$. + 1 just evaluates to TRUE.
Any number 1, 2, 6, or just the $. alone will be true. And give the 2 lines.

( The only special case is $. - xxx where xxx is the next line number. That is false, and the whole thing will print 3 lines. What fun! )

>> my input file has 2 spaces after ... Thus, I using tr command in my script.

Why not ask 'date' to use the right formatting? date +"%e"

>> include only entries from 2010

So grab the year as well. ??

Heck... Why not create the whole regular expression to be used by perl from the date formatting?
For example add ".*" matching anything to skip the time, and lead with ^ to anchor to the line start for faster matching:

$ export DATE=`date +"^%b %e.*%Y"`
$ perl -ne 'print if /$ENV{DATE}/...$.' sudo.log

faster perl using shell variable substitution...

$ perl -ne "print if /$DATE/...\$." sudo.log

Try it?


SEP>> I would not use perl except for fun.
Hmmm, no comment. ( ooops ! :-)

Enjoy,
Hein


Hakki Aydin Ucar
Honored Contributor

Re: perl command line to parse field from a file ??

>Sammy: t seems like your solution may work but my input file has 2spaces after Jul like, "Jul 2" if day is single digit and 1 space after July if "Jul 12". Thus, I using tr command in my script.

In addition;
the easiest way to achieve is to use printf like JRF stated: just an example in shell :

date_formatted=$(printf "%.2d\n" $date)
Hein van den Heuvel
Honored Contributor

Re: perl command line to parse field from a file ??

Hakki wrote>> the easiest way to achieve is to use
>>> printf date_formatted=$(printf "%.2d\n" $date)


Hmmm, how is that easier or more robust than to ask for the correctly formatted number directly with: date +"%e" ???

Using %e, in the unlikely event that %e would ever behave differently, then this program will
still remain in sync with the sudo log as both would use the same method, not something that looks the same.

fwiw,
Hein