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

hi guys can anyone advise me on this piece of code.
#!/usr/bin/perl use strict; use warnings; my $filename = "filet.txt"; my $emailRE='/(\b[\w\.@]+\b)/'; my @emails=(); my $email; my $mail; while (<>) #for each line in each file { @emails = (/($emailRE)/og); #get all the emails on this line foreach $email (@emails) { print "$email, $.\n"; open(FILE, ">$filename") or die "Can't write to $filename: $!"; print FILE $email; } # print them out #close FILE; }

So I am trying to extract data from a file that I use as an argument on the command line. When I print to the screen it shows the extracted information in "$email". I then open the file that I wanted to write to and write "$email" to it but it does not contain all the data that it should i.e. the information seen when I print screen has lot more than what my written file shows.

Replies are listed 'Best First'.
Re: extracting from 1 file and adding to another.
by Corion (Patriarch) on Oct 19, 2013 at 12:01 UTC

    I really recommend you use proper indentation for your blocks. This will make the error quite obvious. Indent the content of each block by four spaces:

    #!/usr/bin/perl use strict; use warnings; my $filename = "filet.txt"; my $emailRE='/(\b[\w\.@]+\b)/'; my @emails=(); my $email; my $mail; while (<>) #for each line in each file { @emails = (/($emailRE)/og); #get all the emails on this line foreach $email (@emails) { print "$email, $.\n"; open(FILE, ">$filename") or die "Can't write to $filename: $!" +; print FILE $email; } # print them out #close FILE; }

    As a second step, I recommend printing out the progress of your program. For example, add a warn statement when you open your output file.

    Also, you may want to learn about the arguments to open. Especially take a look at what > means - it means create-and-overwrite.

      Sorry about the indentation.. trying so many different things at the moment and it got messy. Yes I dont plan to append to the output file just yet. But given I got more than ten or more lines when I printed out "$email" to screen, I would of expected the same to be on the file I had written.

        You don't even have to do the indentation manually, Perl::Tidy will do it for you: $ perltidy your-script.pl (output goes to your-script.pl.tdy). Also, you can get some useful information from Perl::Critic:

        $ perlcritic your-script.pl Loop iterator is not lexical at line 13, column 1. See page 108 of PB +P. (Severity: 5) Bareword file handle opened at line 15, column 1. See pages 202,204 o +f PBP. (Severity: 5) Two-argument "open" used at line 15, column 1. See page 207 of PBP. +(Severity: 5)

        Update: As for your concrete problem, can you supply some (scrambled) input data?

        Well done is better than well said. -- Benjamin Franklin

        Spot on for that ">" nudge. But I seem to missing the concept of it... I thought using >> was to add on to a file without overwriting. Didnt think it was necessary for the first file write. I still dont have it right but using that method atleast adds a bit more to my file.