Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Printing Last Element of a line using perl memory?

by symgryph (Sexton)
on Feb 14, 2013 at 23:40 UTC ( [id://1018813]=perlquestion: print w/replies, xml ) Need Help??

symgryph has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to get a script that will print the last line of some PIX files I have.
access-list blah extended permit tcp object-group blah_Assets object-g +roup mygroup eq www
My script follows:
#!/usr/bin/perl -w while (<>) { m#(\w+$)#; print "$1\n"; }

Yet nothing seems to match even when I use memory. I know the regex is right, I verified that with regex coach. I want to match 'www' in the above example and print it. Any ideas?

"Two Wheels good, Four wheels bad."

Replies are listed 'Best First'.
Re: Printing Last Element of a line using perl memory?
by 7stud (Deacon) on Feb 15, 2013 at 01:03 UTC

    When you are having trouble with regex matching, and you are certain your regex is correct, then it's time to check exactly what's in the string you're matching. One trick is to do this:

    say "-->$string<--";

    Any trailing whitespace will be apparent:

    -->hello world <---

    And if there is a newline at the end of the string, you'll see something like this:

    -->hello world <--

    Or if you want to reveal every character's ascii code, you can do this:

    printf "%vd \n", $string; --output:-- 92.120.50.49.104.101.108.108.111
    Edit: the printf applies ord() to the characters, so the printf is not limited to ascii characters.
      Or if you want to reveal every character in your string's ascii code, you can do this: printf "%vd \n", $string;

      Thanks for that. I had no idea it existed.

      And (IMO) even better is that is led me to just try: printf "%vx\n", $s;. And whaddayaknow. It worked!

      I'll be making much use of that in future.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        You can even get a little fancier if you want:

        my $string = "\x15hello"; printf "%#*vx \n", " ", $string; --output:-- 0x15 0x68 0x65 0x6c 0x6c 0x6f

        And the printf() actually reveals every character's ord(), so it's not confined to ascii characters.

Re: Printing Last Element of a line using perl memory?
by hippo (Bishop) on Feb 14, 2013 at 23:54 UTC

    I do not think that regex will work if you have trailling whitespace in your input data (which there appears to be in your example above). To deal with that, try something like

    m/(\w+)\W*$/;

    instead and see how you get on.

      Might just be style but I'd make the trailing whitespace removal a bit more specific ("\W" to "\s"):

      m/(\w+)\s*$/;

Re: Printing Last Element of a line using perl memory?
by pemungkah (Priest) on Feb 15, 2013 at 01:49 UTC
    A somewhat different way of doing it:
    perl -lne 's[\A\s+][]; s[\s+\Z][]; $last=pop [split /\s+/] if $_; END +{ print $last }' scan.log
    • -l auto-chomps
    • -n wraps the code in a while(<>){ ... }
    • The substitutions remove leading and trailing blanks
    • The split extracts the words in the line (whitespace-separated)
    • The pop takes the last word
    • We save this for each line
    • At end of file, we print the current last word, which will be from the last line
      > The pop takes the last word

      Version warning! =)

      not with < 5.14

      DB<100> $_=join " ",a..z => "a b c d e f g h i j k l m n o p q r s t u v w x y z" DB<101> $x= pop [ split / / ] ;; Type of arg 1 to pop must be array (not anonymous list ([])) at (eval +20)[multi_perl5db.pl:644] line 2, at EOF DB<102> $x= pop @{[ split / / ]} # Workaround => "z"

      Cheers Rolf

        Thanks! Filing that one.

      ++ for the END block idea. A further tweak would be to not process data in the main loop, but only the END block. Unfortunately I could not think of a slick way to make $_ available to END from the last loop iteration, so I had to cheat a little to golf your solution. Apparently the autosplit array does remain resident:

      perl -nae 'END { print "$F[-1]\n"; }' scan.log

      Good examples like yours are weaning me from sed ;-)

        Ooh, nice! I'll use that one too.
Re: Printing Last Element of a line using perl memory?
by nvivek (Vicar) on Feb 15, 2013 at 06:26 UTC

    If we want to print last line of any file, we can use the following code.

    use strict; use warnings; # open the file using _ to avoid multiple system calls invoked by perl open _,"filename"; # reading all lines from a file and store it into @lines array my @lines=<_>; # printing the last line of a file in @lines by $#lines => last index +of the array print @lines[$#lines];
      That code is bad in so many ways.
      # open the file using _ to avoid multiple system calls invoked by perl open _,"filename";
      This is complete nonsense. Using an underscore as the filename makes no difference to the execution, but makes the code harder to understand. Also, you should normally use lexical filehandles. Lastly, there's no error checking on the open.

      my @lines=<_>;
      This will crash with memory exhaustion if the file is too large
      @lines[$#lines];
      With warnings enabled, that will give:
      Scalar value @lines[$#lines] better written as $lines[$#lines]
      But could be even better written as
      $lines[-1]

      Dave.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1018813]
Approved by igelkott
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (6)
As of 2024-04-19 06:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found