Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

How do i extract 3 variables from each line in a file, and print them to a new file

by my_perl (Initiate)
on Jul 08, 2005 at 16:06 UTC ( #473466=perlquestion: print w/ replies, xml ) Need Help??
my_perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi, each line in my file is in format 3434 34456 7788 9999 65444 4 444 444 44443225 12ms:233ms:455ms
755655 5789 333 666776 5553 353534 33 321ms:543ms:45ms
I would like to extract those last 3 numbers and print them coma separated to a new file. These numbers can be 1 - 3 digits length. output should look like this
12,233,455
321,543,45
Thanks

Comment on How do i extract 3 variables from each line in a file, and print them to a new file
Re: How do i extract 3 variables from each line in a file, and print them to a new file
by monarch (Priest) on Jul 08, 2005 at 16:14 UTC
    If you just want the last 3 numbers in a line you can use a regular expression:
    my $line = "3434 34456... 321ms:543ms:45ms"; if ( $line =~ m/(\d+)\D+(\d+)\D+(\d+)\D+$/ ) { print( "$1,$2,$3\n" ); }
Re: How do i extract 3 variables from each line in a file, and print them to a new file
by bofh_of_oz (Hermit) on Jul 08, 2005 at 16:14 UTC
    I believe this line should do it:

    $_ =~ /(\d+)ms/g; print "$1,$2,$3\n";

    UPDATE: I agree with comments since I've got the same result... Here's what worked:

    $_ = "3434 34456... 321ms:543ms:45ms"; ($d, $e, $f) = ($_ =~ /(\d+)ms/g); print "$d,$e,$f\n";

    --------------------------------
    An idea is not responsible for the people who believe in it...

      perl -le '$_="123ms456ms789ms"; $_ =~ /(\d+)ms/g; print "$1,$2,$3\n"; +'
      prints just 123,,

      Capturing doesn't work like that. You are overwriting $1 for each match.

      Try something like

      my @nums = $_ =~ /(\d+)ms/g;
      if you want to capture all matches from a /g.

Re: How do i extract 3 variables from each line in a file, and print them to a new file
by davidrw (Prior) on Jul 08, 2005 at 16:16 UTC
    you'll probably see a bunch of different ways, including split .. here's one pure regex way:
    open OUTFILE, ">out.txt"; open INFILE, "in.txt"; while(<INFILE>){ next unless /(\d{1,3})ms:(\d{1,3})ms:(\d{1,3})ms/; print OUTFILE join(",", ($1, $2, $3) ), "\n"; } close OUTFILE; close INFILE;
      That one is an almost complete solution... Mine is shorter; this one should give the closest match... Add "$" at the end of your regex and it will be perfect...

      --------------------------------
      An idea is not responsible for the people who believe in it...

        your solution didn't work ...

        Yeah, i guess i could anchor to the end (especially since OP said 'last 3 numbers' but might be able to assume that the ":ms" strings in there will be restrictive enought to get the right one.. i guess to go strictly by 'last 3 numbers' the (\d+)\D+ solution above is better (though in that one i would make the last \D+ a \D*)..
Re: How do i extract 3 variables from each line in a file, and print them to a new file
by Transient (Hermit) on Jul 08, 2005 at 16:56 UTC
    TMTOWTDI - and it's usually wrong silly...
    #!/usr/bin/perl use warnings; use strict; open( OUTPUT, ">output" ) or die "Unable to open output\n$!\n"; $,=","; $\="\n"; while (<DATA>) { print OUTPUT map { $_ =~ s/\D//g; $_ } split(':',(split(' ',$_))[-1]) +; } close OUTPUT or die "Close output failed\n$!\n"; __DATA__ 3434 34456 7788 9999 65444 4 444 444 44443225 12ms:233ms:455ms 755655 5789 333 666776 5553 353534 33 321ms:543ms:45ms
    Update: ...and the finale:

    perl -pe '$_=join(",",map{s/\D//g;$_} split(":",(split(" ",$_))[-1])). +"\n"' < input > output
      Check this Data.dat contains the input lines. This is working. open(Spooler, "Data.dat") or die "File does not exists\n"; while($spooler=<Spooler>) { #print "$spooler\n"; chomp($spooler); @matches = $spooler =~ /(\d+)ms/g; foreach $a (@matches){ print $a .","; } print "\n"; } Hope it helps!
        Thanks, that worked great:)
        That would print a comma at the end of the output string, so you would need a way to prevent it, let's say, like this:

        for (@matches) { print "$_,"; } print "\b ";

        (Sorry about replacing foreach with for - someone mentioned to me earlier that it's faster and works the same way anyways)

        Personally, I prefer Transient's way of doing things... although I don't quite understand why it parses split first and then map...

        --------------------------------
        An idea is not responsible for the people who believe in it...

        instead of
        @matches = $spooler =~ /(\d+)ms/g; foreach $a (@matches){ print $a .","; } print "\n";
        how about
        print join(',',$spooler=~/(\d+)ms/g)."\n";
Re: How do i extract 3 variables from each line in a file, and print them to a new file
by bageler (Hermit) on Jul 08, 2005 at 18:02 UTC
    Here is a solution without using any regular expressions:
    $_="22 34808 934 20987129 83454 34643 12ms:34ms:56ms"; @f = unpack("A2A2A3A2A3A2",reverse $_); print join(',',map{join'',scalar reverse}@f[5,3,1]);

    Update: didn't read the problem fully. This is an incomplete solution.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://473466]
Approved by Joost
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2015-07-07 01:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (86 votes), past polls