Re: How to use Text::Wrap correctly
I have a utility I use to wrap logging lines and make them easier to look at. It has different features than you want but down in the core might be a few clues of some use. Without options it generates output like the below: $ wrap /var/log/mail.log Aug 23 10:39:52 crf postfix/pickup[12668]: 1B311848F4: uid=999 from= Aug 23 10:39:52 crf postfix/cleanup[17631]: 1B311848F4: message-id=<20170823163952.1b31184...@crf.b.comcast.net> Aug 23 10:39:52 crf postfix/qmgr[1603]: 1B311848F4: from=, size=8375, nrcpt=1 (queue active) Aug 23 10:39:52 crf postfix/local[17635]: 1B311848F4: to=, orig_to=, relay=local, delay=0.1, delays=0.07/0/0/0.03, dsn=2.0.0, status=sent (delivered to mailbox) Aug 23 10:39:52 crf postfix/qmgr[1603]: 1B311848F4: removed See pasted code below the cut line: ---8<-8<-- #!/usr/bin/env perl use Modern::Perl; use Text::Wrap 'wrap'; use Term::ANSIColor; use Getopt::Long; my @fg = qw( BLACK RED GREEN YELLOW BLUEMAGENTA CYANWHITE BRIGHT_BLACKBRIGHT_REDBRIGHT_GREENBRIGHT_YELLOW BRIGHT_BLUE BRIGHT_MAGENTABRIGHT_CYAN BRIGHT_WHITE ); my @bg = qw( ON_BLACKON_REDON_GREENON_YELLOW ON_BLUE ON_MAGENTAON_CYAN ON_WHITE ON_BRIGHT_BLACK ON_BRIGHT_RED ON_BRIGHT_GREEN ON_BRIGHT_YELLOW ON_BRIGHT_BLUE ON_BRIGHT_MAGENTA ON_BRIGHT_CYAN ON_BRIGHT_WHITE ); my @standout_color = ( 'BLACK ON_YELLOW', 'BLACK ON_RED', 'BLACK ON_GREEN', 'BLACK ON_BRIGHT_RED', 'BLACK ON_BRIGHT_YELLOW', 'RED ON_BRIGHT_GREEN', 'GREEN ON_BLACK', 'RED ON_BRIGHT_CYAN', 'WHITE ON_BLACK', 'WHITE ON_RED', 'WHITE ON_MAGENTA', 'BRIGHT_WHITE ON_RED', 'BRIGHT_WHITE ON_BLUE', 'BRIGHT_WHITE ON_CYAN', 'BRIGHT_WHITE ON_MAGENTA', 'BRIGHT_WHITE ON_CYAN', ); my %opt; GetOptions (\%opt, 'demo+' => sub{ demo(); exit 1}, map{ sprintf('%s|%s=s', $_, lc($_))} @fg, @bg, ) or die "bad options"; sub colorize { my $color = shift; my $text = shift; return $text unless $opt{$color}; my $re = qr($opt{$color}); return $text =~ s/($re)/color($color).$1.color('RESET')/egr; } my %seen; while (<>) { chomp $_; my $t = wrap("", "\t", $_); $t = colorize($_, $t) for (@fg, @bg); say $t; } sub demo { for my $f (@fg) { for my $b (@bg) { say color($f).color($b).$f.' '.$b.color('RESET'); } } } On Tue, Aug 22, 2017 at 5:11 PM, Harry Putnam wrote: > rea...@newsguy.com (Harry Putnam) writes: > > > So trying to simplify things I'm running the script against 3 log > > lines produced by sendmail. The 3 lines below are in a file named > > `mail-loglines'. > > Instead of simplifying I made a mess of things... I left this line at > the bottom of the script: > > __DATA__ > > I meant to comment it out, and even had some log lines at the > bottom.. couldn't have botched it any worse. But wait, oh yes I could. > > > Now in the course of pawing thru this tiny script enough times, I > finally discovered the main problem: > > This line: > print wrap('','', $line); > > Should contain Two single quotes on each side of the first comma. > > Instead I managed to put a single double quote in each spot. > > print wrap(",", $line); wrong > > print wrap('','', $line); right > > With that correction the script acts like it should: > > --- --- ---=--- --- --- > > linewrp 'Aug' ./mail-loglines > > Aug 13 19:59:10 u0 postfix/smtp[7922]: 1993C180CB9: > to=, relay=smtp.fastmail.com[66.111.4.139]:587, > delay=0.7, delays=0.15/0.08/0.35/0.11, dsn=2.0.0, status=sent (250 > 2.0.0 Ok: queued as 7240B7F986) > > Aug 13 19:59:10 u0 postfix/cleanup[7920]: B5619180CBB: > > Aug 13 19:59:11 u0 spamd[831]: spamd: result: . 0 - > DKIM_ADSP_NXDOMAIN,NO_RELAYS > scantime=0.3,size=2008,user=reader,uid=1000,required_score=5.0,rhos > t=localhost,raddr=::1,rport=56648,mid=<20170813235910.B5619180CBB@u > 1>,autolearn=no autolearn_force=no > > --- --- ---=--- --- --- > > It is embarassing, but also a waste of your time, and for that I do > apologize. > > -- > To unsubscribe, e-mail: beginners-unsubscr...@perl.org > For additional commands, e-mail: beginners-h...@perl.org > http://learn.perl.org/ > > >
Re: How to use Text::Wrap correctly
rea...@newsguy.com (Harry Putnam) writes: > So trying to simplify things I'm running the script against 3 log > lines produced by sendmail. The 3 lines below are in a file named > `mail-loglines'. Instead of simplifying I made a mess of things... I left this line at the bottom of the script: __DATA__ I meant to comment it out, and even had some log lines at the bottom.. couldn't have botched it any worse. But wait, oh yes I could. Now in the course of pawing thru this tiny script enough times, I finally discovered the main problem: This line: print wrap('','', $line); Should contain Two single quotes on each side of the first comma. Instead I managed to put a single double quote in each spot. print wrap(",", $line); wrong print wrap('','', $line); right With that correction the script acts like it should: --- --- ---=--- --- --- linewrp 'Aug' ./mail-loglines Aug 13 19:59:10 u0 postfix/smtp[7922]: 1993C180CB9: to=, relay=smtp.fastmail.com[66.111.4.139]:587, delay=0.7, delays=0.15/0.08/0.35/0.11, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 7240B7F986) Aug 13 19:59:10 u0 postfix/cleanup[7920]: B5619180CBB: Aug 13 19:59:11 u0 spamd[831]: spamd: result: . 0 - DKIM_ADSP_NXDOMAIN,NO_RELAYS scantime=0.3,size=2008,user=reader,uid=1000,required_score=5.0,rhos t=localhost,raddr=::1,rport=56648,mid=<20170813235910.B5619180CBB@u 1>,autolearn=no autolearn_force=no --- --- ---=--- --- --- It is embarassing, but also a waste of your time, and for that I do apologize. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: How to use Text::Wrap correctly
jimsgib...@gmail.com (Jim Gibson) writes: > There is an error in what I posted (sorry). The input is read into > the $line variable, but your regular expression is implicitly > testing the default variable $_. The loop should be: > > > while ( my $line = <> ) { > if ( $line =~ /$rgx/ ) { > print "\n"; > print wrap(",", $line); > } > } > > I don’t know what Text::Wrap is complaining about. It helps if you > are able to include a text string in your posted source code that > demonstrates the problem. Use the built-in DATA file handle to > include data within your program source. Check out ‘perldoc > perldata’ and search for “__DATA__”. This is the pattern: > > ... > while ( my $line = ) { > if ( $line =~ /$rgx/ ) { > print "\n"; > print wrap(",", $line); > } > } > ... > __DATA__ > This is data to be read using the operation. I am really sorry here. I'm not able to make sense of how this is done even though you've given some hefty clues. That section of perldoc perldata with `__DATA__' in it reads like some kind of riddle. I guess I'm not understanding it even a little. The second main paragraph mentioning `__DATA__' says: See SelfLoader for more description of __DATA__, and an example of its use. [...] So I tried my best to follow that too. Especially looking for an example of its use. I guess the example is supposed to be: SYNOPSIS package FOOBAR; use SelfLoader; ... (initializing code) __DATA__ sub { Seems like more riddles. Apparently this is too far above my pay grade. It reads like I should be able to do something like: print $FOOBAR::DATA Which I guess means `print $Text::Wrap::DATA' But of course, that does not work. --- --- ---=--- --- --- Your clues seem to indicate I should be able to do: while ( my $line = ) { if ( $line =~ /$rgx/ ) { print "\n"; print wrap(",", $line); } } ## ... print __DATA__; --- --- ---=--- --- --- But that is not what is needed either. --- --- ---=--- --- --- Is the __DATA__ something more than the lines being read? I mean are we just talking about seeing the incoming lines? I did include the actual log lines at one point. So trying to simplify things I'm running the script against 3 log lines produced by sendmail. The 3 lines below are in a file named `mail-loglines'. Each is all on one line (hopefully this is the DATA you need to see): Aug 13 19:59:10 u0 postfix/smtp[7922]: 1993C180CB9: to=, relay=smtp.fastmail.com[66.111.4.139]:587, delay=0.7, delays=0.15/0.08/0.35/0.11, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 7240B7F986) Aug 13 19:59:10 u0 postfix/cleanup[7920]: B5619180CBB: message-id=<20170813235910.B5619180CBB@u1> Aug 13 19:59:11 u0 spamd[831]: spamd: result: . 0 - DKIM_ADSP_NXDOMAIN,NO_RELAYS scantime=0.3,size=2008,user=reader,uid=1000,required_score=5.0,rhost=localhost,raddr=::1,rport=56648,mid=<20170813235910.B5619180CBB@u1>,autolearn=no autolearn_force=no --- --- ---=--- --- --- The script -- cat linewrp: [...] use strict; use warnings; use Text::Wrap; my $rgx = qr/@{[shift]}/; $Text::Wrap::columns = 68; while ( my $line = <> ) { if ( $line =~ /$rgx/ ) { print "\n"; print wrap(",", $line); } } --- --- ---=--- --- --- The output: linewrp 'Aug' ./mail-loglines Increasing $Text::Wrap::columns from 68 to 220 to accommodate length of subsequent tab at /vcs/2x/export/home/reader/scripts/perl/linewrp line 21. Increasing $Text::Wrap::columns from 220 to 252 to accommodate length of subsequent tab at /vcs/2x/export/home/reader/scripts/perl/linewrp line 21. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: How to use Text::Wrap correctly
> On Aug 18, 2017, at 6:05 AM, Harry Putnam wrote: > > jimsgib...@gmail.com (Jim Gibson) writes: >>> > > A second attempt trying to use your last example as inspiration > follows: > > ---8< snip -8< snip -- > > use strict; > use warnings; > use Text::Wrap; > > my $rgx = qr/@{[shift]}/; > > $Text::Wrap::columns = 68; > > > while ( my $line = <> ) { > if (/$rgx/) { > print "\n"; > print wrap(",", $line); > } > } > > ---8< snip -8< snip -- > > Output from same `logs' file: > > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 1. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 2. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 3. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 4. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 5. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 6. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 7. > Use of uninitialized value $_ in pattern match (m//) at > /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 8. There is an error in what I posted (sorry). The input is read into the $line variable, but your regular expression is implicitly testing the default variable $_. The loop should be: while ( my $line = <> ) { if ( $line =~ /$rgx/ ) { print "\n"; print wrap(",", $line); } } I don’t know what Text::Wrap is complaining about. It helps if you are able to include a text string in your posted source code that demonstrates the problem. Use the built-in DATA file handle to include data within your program source. Check out ‘perldoc perldata’ and search for “__DATA__”. This is the pattern: ... while ( my $line = ) { if ( $line =~ /$rgx/ ) { print "\n"; print wrap(",", $line); } } ... __DATA__ This is data to be read using the operation. Jim Gibson jgib...@snowlands.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: How to use Text::Wrap correctly
jimsgib...@gmail.com (Jim Gibson) writes: >> On Aug 13, 2017, at 6:02 PM, Harry Putnam wrote: >> >> My aim: >> >> Run certain kinds of log file lines thru a perl script that will: >> >> 1) Identify each line by regex that finds pattern at start of line >> 2) When such a line is found, print newline first then >> 3) wrap any lines longer than specified number of columns. >> >> >> I was not able to divine from `perldoc Text::Wrap' how to really use >> it to do what I want. >> >> my non-working effort stripped to the bare bones: >> >> use strict; >> use warnings; >> use Text::Wrap; >> >> my $rgx = qr/@{[shift]}/; >> >> $Text::Wrap::columns = 68; >> >> my @text; >> >> while (<>) { >> if (/$rgx/) { >> print "\n"; >> print wrap(",", @text); >> } >> } >> >> It wasn't at all clear from perldoc Text::Wrap how @text is supposed >> to be populated. > > @text is a list of scalar strings passed to the wrap subroutine. You > can pass a single string also. Try this loop instead: > > while (<>) { > if (/$rgx/) { > print "\n"; > print wrap(",", $_); > } > } > > It is usually better to use explicit variables: > > while ( my $line = <> ) { > if (/$rgx/) { > print "\n"; > print wrap(",", $line); > } > } Apparently I do not have the wisdom necessary to make a working script, even with your patient help. I'm not sure what to make of the ouput: With the script in a configuration resembling your first example: (Note a few lines of sendmail log output in file `logs' posted at the end) ---8< snip -8< snip -- use strict; use warnings; use Text::Wrap; my $rgx = qr/@{[shift]}/; $Text::Wrap::columns = 68; while (<>) { if (/$rgx/) { print "\n"; print wrap(",", $_); } } ---8< snip -8< snip -- logwrp '^Aug ' logs Gets this output: Increasing $Text::Wrap::columns from 68 to 99 to accommodate length of subsequent tab at /vcs/d0/home/reader/scripts/perl/logwrp line 35. Increasing $Text::Wrap::columns from 99 to 146 to accommodate length of subsequent tab at /vcs/d0/home/reader/scripts/perl/logwrp line 35. --- END --- Output included the blank lines as above. --- --- ---=--- --- --- A second attempt trying to use your last example as inspiration follows: ---8< snip -8< snip -- use strict; use warnings; use Text::Wrap; my $rgx = qr/@{[shift]}/; $Text::Wrap::columns = 68; while ( my $line = <> ) { if (/$rgx/) { print "\n"; print wrap(",", $line); } } ---8< snip -8< snip -- Output from same `logs' file: Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 1. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 2. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 3. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 4. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 5. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 6. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 7. Use of uninitialized value $_ in pattern match (m//) at /vcs/d0/home/reader/scripts/perl/logwrp line 48, <> line 8. --- --- ---=--- --- --- Log lines fed to scripts in file `logs' --- --- ---=--- --- --- cat logs Aug 16 19:20:01 d2 sendmail[3470]: NOQUEUE: SYSERR(smmsp): QueueDirectory (Q) option must be set Aug 16 20:45:37 d2 sm-mta[768]: starting daemon (8.14.4): SMTP+queueing@00:10:00 Aug 16 20:45:38 d2 sm-msp-queue[788]: NOQUEUE: SYSERR(root): /etc/mail/submit.cf: line 2: invalid argument to V line: "ERSIONID(\001Id: submit" Aug 16 20:45:38 d2 sm-msp-queue[788]: NOQUEUE: SYSERR(root): No local mailer defined Aug 16 20:45:38 d2 sm-msp-queue[788]: NOQUEUE: SYSERR(root): QueueDirectory (Q) option must be set Aug 16 21:34:28 d2 sendmail[842]: alias database /etc/mail/aliases rebuilt by root Aug 16 21:34:28 d2 sendmail[842]: /etc/mail/aliases: 13 aliases, longest 10 bytes, 144 bytes total Aug 16 21:34:31 d2 sm-mta[877]: starting daemon (8.14.4):SMTP+queueing@00:10:00 -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: How to use Text::Wrap correctly
jimsgib...@gmail.com (Jim Gibson) writes: >> On Aug 13, 2017, at 6:02 PM, Harry Putnam wrote: >> >> My aim: >> [...] >> my @text; >> >> while (<>) { >> if (/$rgx/) { >> print "\n"; >> print wrap(",", @text); >> } >> } >> >> It wasn't at all clear from perldoc Text::Wrap how @text is supposed >> to be populated. > > @text is a list of scalar strings passed to the wrap subroutine. You > can pass a single string also. Try this loop instead: Argh, yes I see > while (<>) { > if (/$rgx/) { > print "\n"; > print wrap(",", $_); > } > } > > It is usually better to use explicit variables: > > while ( my $line = <> ) { > if (/$rgx/) { > print "\n"; > print wrap(",", $line); > } > } Thanks for clearing that up, and the good practices tip. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: How to use Text::Wrap correctly
> On Aug 13, 2017, at 6:02 PM, Harry Putnam wrote: > > My aim: > > Run certain kinds of log file lines thru a perl script that will: > > 1) Identify each line by regex that finds pattern at start of line > 2) When such a line is found, print newline first then > 3) wrap any lines longer than specified number of columns. > > > I was not able to divine from `perldoc Text::Wrap' how to really use > it to do what I want. > > my non-working effort stripped to the bare bones: > > use strict; > use warnings; > use Text::Wrap; > > my $rgx = qr/@{[shift]}/; > > $Text::Wrap::columns = 68; > > my @text; > > while (<>) { > if (/$rgx/) { > print "\n"; > print wrap(",", @text); > } > } > > It wasn't at all clear from perldoc Text::Wrap how @text is supposed > to be populated. @text is a list of scalar strings passed to the wrap subroutine. You can pass a single string also. Try this loop instead: while (<>) { if (/$rgx/) { print "\n"; print wrap(",", $_); } } It is usually better to use explicit variables: while ( my $line = <> ) { if (/$rgx/) { print "\n"; print wrap(",", $line); } } Jim Gibson -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/