Help: Process many files at the same time

Discussion in 'Perl Misc' started by Amy Lee, Sep 30, 2008.

  1. Amy Lee

    Amy Lee Guest

    Hello,

    Here's my codes:

    foreach $file (@ARGV)
    {
    while (<>)
    {
    chomp;
    if (/(\d+)\s+dG = (-?[\d.]+)\s+(.*)/)
    {
    $total = $1;
    $name = $3;
    s/.*//;
    }
    $g += tr/C//;
    $c += tr/G//;
    }
    $gc = $g+$c;
    $GC = $gc/$total;
    print "$name\t$GC\n";
    }
    Then I hope I can get a list of the result because I use "foreach" to
    process many files I gave at the same time. However, It just output one
    file and the output variable $CG is wrong. If I run this to process one
    file, it could work well.

    I don't know what's errors in there.

    Could you tell me what's going on?

    Thanks.

    Amy
    Amy Lee, Sep 30, 2008
    #1
    1. Advertising

  2. Amy Lee <> wrote:
    >Hello,
    >
    >Here's my codes:
    >
    >foreach $file (@ARGV)


    Ok, you are looping through all command line arguments

    >{
    > while (<>)


    For each of those arguments you are reading lines from the keyboard
    until the user submits an EOF.

    Is that what you want?

    jue
    Jürgen Exner, Sep 30, 2008
    #2
    1. Advertising

  3. Amy Lee

    Amy Lee Guest

    On Mon, 29 Sep 2008 20:44:09 -0700, Jürgen Exner wrote:

    > Amy Lee <> wrote:
    >>Hello,
    >>
    >>Here's my codes:
    >>
    >>foreach $file (@ARGV)

    >
    > Ok, you are looping through all command line arguments
    >
    >>{
    >> while (<>)

    >
    > For each of those arguments you are reading lines from the keyboard
    > until the user submits an EOF.
    >
    > Is that what you want?
    >
    > jue

    Thanks. the codes
    while (<>)
    {
    chomp;
    if (/(\d+)\s+dG = (-?[\d.]+)\s+(.*)/)
    {
    $total = $1;
    $name = $3;
    s/.*//;
    }
    $g += tr/C//;
    $c += tr/G//;
    }
    $gc = $g+$c;
    $GC = $gc/$total;
    print "$name\t$GC\n";
    can process one file per time and work well. So I suppose that I can make
    a foreach loop to process many files reads from filenames. But it seems
    not work. So I wonder what's wrong with the codes.

    Could you tell me how to modify that?

    Amy
    Amy Lee, Sep 30, 2008
    #3
  4. On Tue, 30 Sep 2008 11:26:09 +0800,
    Amy Lee <> wrote:
    > Hello,
    >
    > Here's my codes:
    >
    > foreach $file (@ARGV)
    > {
    > while (<>)
    > {


    If you want to read all files on the command line, one after the other,
    simply use

    while (<>) { }

    There's no need to process @ARGV yourself for that.

    See the perlop documentation. Look for the section starting with

    The null filehandle <> is special: it can be used to emulate the behavâ€
    ior of sed and awk

    > Then I hope I can get a list of the result because I use "foreach" to
    > process many files I gave at the same time. However, It just output one
    > file and the output variable $CG is wrong. If I run this to process one
    > file, it could work well.


    I don't believe this. Even with the useless foreach loop around the
    while loop, all files on the command line still should have been
    processed.

    This:


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

    foreach my $file (@ARGV)
    {
    while (<>)
    {
    print;
    }
    }

    Works fine for me, and simply prints the contents of every file I give
    it on the command line to STDOUT. It does this on the FIRST iteration of
    the foreach loop. After this first iteration, @ARGV is empty, so there
    is no second iteration. Since you're not supposed to modify arrays while
    you're iterating over them, I suppose that this is current behaviour,
    and not necessarily guaranteed. in other words: Don't do it. Either
    iterate over @ARGV and handle the files yourself, or use while(<>), and
    let it iterate.

    Martien
    --
    |
    Martien Verbruggen | Make it idiot proof and someone will make a
    | better idiot.
    |
    Martien Verbruggen, Sep 30, 2008
    #4
  5. Amy Lee <> wrote:


    > foreach $file (@ARGV)



    Why do you think you need this foreach loop?

    (hint: where does your program make use of the $file variable?)


    > {
    > while (<>)



    The diamond operator (<>) opens a file (for reading) for you.


    > {
    > chomp;
    > if (/(\d+)\s+dG = (-?[\d.]+)\s+(.*)/)
    > {
    > $total = $1;
    > $name = $3;
    > s/.*//;



    What is in $_ at this point in your program?

    (hint: print it out here.)


    > }
    > $g += tr/C//;
    > $c += tr/G//;



    What string is the tr/// operator operating on here? (Answer: the string in $_).

    What is in $_ at this point? (Answer: either the empty string or a newline).

    How many "C" characters are there in $_ (Answer: zero).

    Repeatedly adding zero to a number will not likely lead to useful results...


    > }
    > $gc = $g+$c;
    > $GC = $gc/$total;



    I anticipate that you will run into yet another Frequently Asked Question,
    so let's get that out of the way right now:

    perldoc -q 999

    Why am I getting long decimals (eg, 19.9499999999999) instead
    of the numbers I should be getting (eg, 19.95)?

    and

    perldoc -q round

    Does Perl have a round() function? What about ceil() and floor()?
    Trig functions?


    > print "$name\t$GC\n";



    Since you have not provided a filehandle to print(), all of the output
    will go to the default stream (STDOUT).

    If you want to write to a file, you must open() it for writing,
    and use the filehandle that the open() set up for you, eg:

    open my $OUTFILE, '>', "$file.new" or die "could not open '$file.new' $!";
    then
    print $OUTFILE "$name\t$GC\n";


    > }
    > Then I hope I can get a list of the result because I use "foreach" to
    > process many files I gave at the same time. However, It just output one
    > file and the output variable $CG is wrong. If I run this to process one
    > file, it could work well.



    perl will handle all of the reading from one file then writing to
    another file for you.

    See the -i switch in perlrun.pod and the $^I variable in perlvar.pod.


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
    Tad J McClellan, Sep 30, 2008
    #5
  6. Amy Lee

    Guest

    On Tue, 30 Sep 2008 08:57:35 -0500, Tad J McClellan <> wrote:

    >Amy Lee <> wrote:
    >
    >
    >> foreach $file (@ARGV)

    >
    >
    >Why do you think you need this foreach loop?
    >
    >(hint: where does your program make use of the $file variable?)
    >
    >
    >> {
    >> while (<>)

    >
    >
    >The diamond operator (<>) opens a file (for reading) for you.
    >
    >
    >> {
    >> chomp;
    >> if (/(\d+)\s+dG = (-?[\d.]+)\s+(.*)/)
    >> {
    >> $total = $1;
    >> $name = $3;
    >> s/.*//;

    >
    >
    >What is in $_ at this point in your program?
    >
    >(hint: print it out here.)
    >
    >
    >> }
    >> $g += tr/C//;
    >> $c += tr/G//;

    >
    >
    >What string is the tr/// operator operating on here? (Answer: the string in $_).
    >
    >What is in $_ at this point? (Answer: either the empty string or a newline).
    >
    >How many "C" characters are there in $_ (Answer: zero).
    >
    >Repeatedly adding zero to a number will not likely lead to useful results...
    >
    >
    >> }
    >> $gc = $g+$c;
    >> $GC = $gc/$total;

    >
    >
    >I anticipate that you will run into yet another Frequently Asked Question,
    >so let's get that out of the way right now:
    >
    > perldoc -q 999
    >
    > Why am I getting long decimals (eg, 19.9499999999999) instead
    > of the numbers I should be getting (eg, 19.95)?
    >
    >and
    >
    > perldoc -q round
    >
    > Does Perl have a round() function? What about ceil() and floor()?
    > Trig functions?
    >
    >
    >> print "$name\t$GC\n";

    >
    >
    >Since you have not provided a filehandle to print(), all of the output
    >will go to the default stream (STDOUT).
    >
    >If you want to write to a file, you must open() it for writing,
    >and use the filehandle that the open() set up for you, eg:
    >
    > open my $OUTFILE, '>', "$file.new" or die "could not open '$file.new' $!";
    >then
    > print $OUTFILE "$name\t$GC\n";
    >
    >
    >> }
    >> Then I hope I can get a list of the result because I use "foreach" to
    >> process many files I gave at the same time. However, It just output one
    >> file and the output variable $CG is wrong. If I run this to process one
    >> file, it could work well.

    >
    >
    >perl will handle all of the reading from one file then writing to
    >another file for you.
    >
    >See the -i switch in perlrun.pod and the $^I variable in perlvar.pod.


    You are the atypical prototype ball buster ain't ya?

    sln
    , Oct 5, 2008
    #6
    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. Replies:
    2
    Views:
    648
  2. dee
    Replies:
    2
    Views:
    391
  3. elaine
    Replies:
    2
    Views:
    309
    elaine
    Jan 30, 2007
  4. flamesrock
    Replies:
    8
    Views:
    438
    Hendrik van Rooyen
    Nov 24, 2006
  5. franckspike
    Replies:
    1
    Views:
    319
    Boris
    Jul 3, 2008
Loading...

Share This Page