list of numbers

Discussion in 'Perl Misc' started by Andrew Moffat, Sep 7, 2004.

  1. Hi,

    I have lots of files with three columns of numbers e.g.

    1 2 3
    4.1 5 6
    7 8 9
    ......etc

    I want to extract the third column e.g.

    3
    6
    9
    .....etc

    The problem is that I can't just use a colrm type function because the
    numbers in the first 2 columns aren't always the same number of figures (as
    above). Each number is seperated by a tab. Can anybody think of a way around
    this please. TIA.
    Andrew Moffat, Sep 7, 2004
    #1
    1. Advertising

  2. Andrew Moffat <> wrote in message
    <news:chkg25$ajd$>:

    > I have lots of files with three columns of numbers

    [snip]
    > Each number is seperated by a tab. Can
    > anybody think of a way around this please.


    perldoc -f split
    David K. Wall, Sep 7, 2004
    #2
    1. Advertising

  3. Andrew Moffat

    Sandman Guest

    In article <chkg25$ajd$>,
    "Andrew Moffat" <> wrote:

    > Hi,
    >
    > I have lots of files with three columns of numbers e.g.
    >
    > 1 2 3
    > 4.1 5 6
    > 7 8 9
    > .....etc
    >
    > I want to extract the third column e.g.
    >
    > 3
    > 6
    > 9
    > ....etc
    >
    > The problem is that I can't just use a colrm type function because the
    > numbers in the first 2 columns aren't always the same number of figures (as
    > above). Each number is seperated by a tab. Can anybody think of a way around
    > this please. TIA.


    #!/usr/bin/perl
    use strict;
    use warnings;

    my $data = "1\t2\t3
    4.1\t5\t6
    7\t8\t9";

    foreach (split /\n/, $data){
    my @cols = split /\t/;
    print $cols[2] . "\n";
    }

    __END__
    3
    6
    9

    --
    Sandman[.net]
    Sandman, Sep 7, 2004
    #3
  4. Andrew Moffat

    Tore Aursand Guest

    On Tue, 07 Sep 2004 15:19:57 +0100, Andrew Moffat wrote:
    > I have lots of files with three columns of numbers e.g.
    >
    > 1 2 3
    > 4.1 5 6
    > 7 8 9
    > .....etc
    >
    > I want to extract the third column e.g.
    >
    > 3
    > 6
    > 9
    > ....etc
    >
    > The problem is that I can't just use a colrm type function because the
    > numbers in the first 2 columns aren't always the same number of figures (as
    > above). Each number is seperated by a tab. Can anybody think of a way around
    > this please.


    Hmmm. This is a tough one. How can I use Perl to split() something? I
    know I've read about that somewhere, but where...? Was it in the Perl
    documentation? Nah - that would've been too obvious, don't you think?
    Yeah, I won't even bother to check...


    --
    Tore Aursand <>
    "Nothing is certain but death and taxes. Of the two, taxes happen
    annually." (Joel Fox)
    Tore Aursand, Sep 7, 2004
    #4
  5. Andrew Moffat

    gumby Guest

    Sandman <> wrote in message news:<>...
    > In article <chkg25$ajd$>,
    > "Andrew Moffat" <> wrote:
    >
    > > Hi,
    > >
    > > I have lots of files with three columns of numbers e.g.
    > >
    > > 1 2 3
    > > 4.1 5 6
    > > 7 8 9
    > > .....etc
    > >
    > > I want to extract the third column e.g.
    > >
    > > 3
    > > 6
    > > 9
    > > ....etc
    > >
    > > The problem is that I can't just use a colrm type function because the
    > > numbers in the first 2 columns aren't always the same number of figures (as
    > > above). Each number is seperated by a tab. Can anybody think of a way around
    > > this please. TIA.

    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my $data = "1\t2\t3
    > 4.1\t5\t6
    > 7\t8\t9";
    >
    > foreach (split /\n/, $data){
    > my @cols = split /\t/;
    > print $cols[2] . "\n";
    > }
    >
    > __END__
    > 3
    > 6
    > 9



    Here is another of of attacking the problem. I realize this may get
    out of hand if you have quite a few columns but its just a thought.
    the test file contains the following data:

    1 2 3
    4.1 5 6
    7 8 9

    The Code:

    unless(open FILE, test)
    {
    print "Failed to open the test file ($!).\n";
    }

    while(<FILE>)
    {
    my $line = $_;
    $line =~ /([0-9.]+)\s+([0-9.]+)\s+([0-9]+)/;
    print "$1 and $2 and $3\n";
    }

    close FILE;

    The Output:
    1 and 2 and 3
    4.1 and 5 and 6
    7 and 8 and 9

    As you can see $(number) is the column you want as you rip through
    the file. You can push the column onto an array using something like
    push(@array, $3) and that would push the contents of each line in
    column three onto @array. There is probably a \(letter) that will do
    decimal numbers i know \d does digits. Anyway hope this helps
    -gumby
    gumby, Sep 7, 2004
    #5
  6. Andrew Moffat

    Paul Lalli Guest

    "gumby" <> wrote in message
    news:...
    > Sandman <> wrote in message

    news:<>...
    > > In article <chkg25$ajd$>,
    > > "Andrew Moffat" <> wrote:
    > >
    > > > Hi,
    > > >
    > > > I have lots of files with three columns of numbers e.g.
    > > >
    > > > 1 2 3
    > > > 4.1 5 6
    > > > 7 8 9
    > > > .....etc
    > > >
    > > > I want to extract the third column e.g.
    > > >
    > > > 3
    > > > 6
    > > > 9
    > > > ....etc

    > Here is another of of attacking the problem. I realize this may get
    > out of hand if you have quite a few columns but its just a thought.


    That's precisely why you should use split instead of RegExps in this
    case. Someone wise once said "Use Regexps when you know what you want
    to save, use split when you know what you want to throw away." You
    don't (necessarily) know what you want to save - how many columns there
    are. You do know what you want to throw away - all the space between
    the fields, regardless of how many there are.

    > the test file contains the following data:
    >
    > 1 2 3
    > 4.1 5 6
    > 7 8 9
    >
    > The Code:
    >
    > unless(open FILE, test)
    > {
    > print "Failed to open the test file ($!).\n";
    > }


    If the file fails to open, you print a message to STDOUT, and then keep
    going with the program? This should be

    open my $file, 'test' or die "Failed to open the test file ($!).";

    >
    > while(<FILE>)

    while (<$file>)
    > {
    > my $line = $_;
    > $line =~ /([0-9.]+)\s+([0-9.]+)\s+([0-9]+)/;


    why reassign $_ to $line if all you're doing is pattern matching it one
    statement later?

    > print "$1 and $2 and $3\n";


    Never, ever use $1, $2, $3 unless you know the pattern match succeeded.
    You never check for that.

    Another reason to not use regexps here: What if the numbers are in the
    format such as -0.9? How about 5e4? Again, you know what you want to
    throw away, you don't know what you want to keep.

    > }
    >
    > close FILE;
    >
    > The Output:
    > 1 and 2 and 3
    > 4.1 and 5 and 6
    > 7 and 8 and 9
    >
    > As you can see $(number) is the column you want as you rip through
    > the file. You can push the column onto an array using something like
    > push(@array, $3) and that would push the contents of each line in
    > column three onto @array. There is probably a \(letter) that will do
    > decimal numbers i know \d does digits.


    No, there's not. There is a module on the CPAN that will allow you to
    specify exactly what kinds of numbers you want, however.
    Regexp::Common, I believe.

    > Anyway hope this helps
    > -gumby


    Paul Lalli
    Paul Lalli, Sep 7, 2004
    #6
  7. Andrew Moffat

    Tore Aursand Guest

    On Tue, 07 Sep 2004 12:18:49 -0700, gumby wrote:
    > Here is another of of attacking the problem. I realize this may get out
    > of hand if you have quite a few columns but its just a thought. the test
    > file contains the following data:
    >
    > 1 2 3
    > 4.1 5 6
    > 7 8 9
    >
    > The Code:
    >
    > unless(open FILE, test)
    > {
    > print "Failed to open the test file ($!).\n";
    > }


    Why continue if there's no point in continuing? Why should you even _try_
    to read from the file if you didn't succeed in opening it?

    > while(<FILE>)
    > {
    > my $line = $_;
    > $line =~ /([0-9.]+)\s+([0-9.]+)\s+([0-9]+)/;
    > print "$1 and $2 and $3\n";
    > }


    Blah. A hairy regular expression instead of the easy split() function?
    And why assign $_ to $line, instead of directly? And what happens if the
    regular expression doesn't match?

    while ( <FILE> ) {
    if ( ... ) {
    # match
    }
    }


    --
    Tore Aursand <>
    "I didn't have time to write a short letter, so I wrote a long one
    instead." (Mark Twain)
    Tore Aursand, Sep 7, 2004
    #7
  8. In article <chkg25$ajd$>,
    Andrew Moffat <> wrote:
    >Hi,
    >
    >I have lots of files with three columns of numbers e.g.
    >
    >1 2 3
    >4.1 5 6
    >7 8 9
    >.....etc
    >
    >I want to extract the third column e.g.
    >
    >3
    >6
    >9
    >....etc
    >
    >The problem is that I can't just use a colrm type function because the
    >numbers in the first 2 columns aren't always the same number of figures (as
    >above). Each number is seperated by a tab. Can anybody think of a way around
    >this please. TIA.
    >


    Unix: perl -F\\t -lane 'print $F[2]' file1 file2...

    W2K: perl -F\t -lane "print $F[2]" file1 ...

    hth,
    --
    Charles DeRykus
    Charles DeRykus, Sep 8, 2004
    #8
  9. On Wed, 8 Sep 2004 04:29:46 GMT, (Charles
    DeRykus) wrote:

    >>1 2 3
    >>4.1 5 6
    >>7 8 9
    >>.....etc
    >>
    >>I want to extract the third column e.g.

    [snip]
    >Unix: perl -F\\t -lane 'print $F[2]' file1 file2...
    >
    >W2K: perl -F\t -lane "print $F[2]" file1 ...


    Going down the golfing route, I'd suggest

    perl -lape'$_=pop@F'

    (-a defaults split()ting on whitespace and "\t" *is* whitespace.)
    Without the need of being so drastic, though, it is amazing to see
    what kind of clumsy solutions have been posted to this simple
    problem...


    Michele
    --
    #!/usr/bin/perl -lp
    BEGIN{*ARGV=do{open $_,q,<,,\$/;$_}}s z^z seek DATA,11,$[;($,
    =ucfirst<DATA>)=~s x .*x q^~ZEX69l^^q,^2$;][@,xe.$, zex,s e1e
    q 1~BEER XX1^q~4761rA67thb ~eex ,s aba m,P..,,substr$&,$.,age
    __END__
    Michele Dondi, Sep 8, 2004
    #9
  10. On Thu, 09 Sep 2004 23:36:36 GMT, Ala Qumsieh <>
    wrote:

    >> perl -lape'$_=pop@F'

    >
    >Golf, eh?
    >
    > perl -pe's/.*\t//'


    D'Oh!


    Michele (who is slightly ashamed because he's been thinkg of this very
    same solution *in connection with sed* mentioned in Abigail's post,
    and even does something similar with either "/" or "\." instead of
    "\t" almost on a daily basis either with perl or sed...),
    --
    you'll see that it shouldn't be so. AND, the writting as usuall is
    fantastic incompetent. To illustrate, i quote:
    - Xah Lee trolling on clpmisc,
    "perl bug File::Basename and Perl's nature"
    Michele Dondi, Sep 10, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Subra
    Replies:
    25
    Views:
    1,169
    user923005
    Mar 8, 2007
  2. Andrew Tatum

    Fibonacci Numbers and Lucas Numbers

    Andrew Tatum, May 26, 2007, in forum: C++
    Replies:
    6
    Views:
    540
    Howard
    May 27, 2007
  3. Lance Hoffmeyer
    Replies:
    2
    Views:
    511
    Lance Hoffmeyer
    Jul 26, 2007
  4. jko170
    Replies:
    9
    Views:
    113
    jko170
    Jan 21, 2009
  5. GIMME
    Replies:
    5
    Views:
    177
    Thomas 'PointedEars' Lahn
    Jul 26, 2004
Loading...

Share This Page