Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Extract text from a file and write to another. (http://www.velocityreviews.com/forums/t884946-extract-text-from-a-file-and-write-to-another.html)

Sesa Woruban 02-01-2004 05:11 PM

Extract text from a file and write to another.
 
Hiya,

I'm very new to Perl and my brain is dead. I'm trying to create a
simple programme that will extract the pertinent lines (only those
with a : in them) from a plain flat text file (that represents my
inbox) and write only those files to another text file. This is what
I've got so far:

use strict;
use warnings;

my $key;
my %hash;
my $infile = '/home/sesaworu/mail/sesaworuban.net/test/input'; #
store the file
my $outfile = '>/home/sesaworu/mail/sesaworuban.net/test/output.txt';
open (INFILE, $infile) or die "cannot open $infile: $!"; # opens the
file
open (OUTFILE, $outfile) or die "cannot open $outfile: $!"; # opens
the file

while()
{
chomp;
$key='',next if /^\s*$/;
if(/([\w\s]+):(.*)/){
$key=$1;
push @{$hash{$key}},$2;
}
else
{
push @{$hash{$key}},$_ if $key;
}
}
for(sort keys %hash)
{
print OUTFILE "$_ : ".join("\n",@{$hash{$_}})."\n";
}

How does that look?

Cheers
Sesa

Ben Morrow 02-01-2004 05:24 PM

Re: Extract text from a file and write to another.
 

me@sesaworuban.net (Sesa Woruban) wrote:
> use strict;
> use warnings;


Good.

> my $key;
> my %hash;


Give this a better name, like %headers.

> my $infile = '/home/sesaworu/mail/sesaworuban.net/test/input'; #
> store the file


There's no need for that comment: it is perfctly clear from the code.

> my $outfile = '>/home/sesaworu/mail/sesaworuban.net/test/output.txt';
> open (INFILE, $infile) or die "cannot open $infile: $!"; # opens the
> file


I would recommend using a lexical FH:

open my $IN, $infile or die "cannot open $infile: $!";

> open (OUTFILE, $outfile) or die "cannot open $outfile: $!"; # opens
> the file
>
> while()
> {


You mean
while (<INFILE>) {

> chomp;
> $key='',next if /^\s*$/;


Use undef rather than ''... it's a better representation of 'no
value'.

> if(/([\w\s]+):(.*)/){


This is a mail message, right? In which case, don't you mean something
more like /(.+?) \s* : \s* (.*)/x ? '-' is not included in \w. Also,
do you know that a continuation header line can (and often will) contain
':': it is the whitespace at the start which marks it as a
continuation?

If this is a mailbox, you would be better off using one of the Mail::
modules on CPAN to parse it.

> $key=$1;
> push @{$hash{$key}},$2;
> }
> else
> {
> push @{$hash{$key}},$_ if $key;
> }
> }
> for(sort keys %hash)
> {
> print OUTFILE "$_ : ".join("\n",@{$hash{$_}})."\n";
> }


Ben

--
If I were a butterfly I'd live for a day, / I would be free, just blowing away.
This cruel country has driven me down / Teased me and lied, teased me and lied.
I've only sad stories to tell to this town: / My dreams have withered and died.
ben@morrow.me.uk <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=> (Kate Rusby)

Jürgen Exner 02-01-2004 05:40 PM

Re: Extract text from a file and write to another.
 
Sesa Woruban wrote:
> I'm very new to Perl and my brain is dead. I'm trying to create a
> simple programme that will extract the pertinent lines (only those
> with a : in them) from a plain flat text file (that represents my
> inbox) and write only those files to another text file. This is what
> I've got so far:
>
> use strict;
> use warnings;


Good and good!

> my $key;
> my %hash;
> my $infile = '/home/sesaworu/mail/sesaworuban.net/test/input'; #
> store the file
> my $outfile = '>/home/sesaworu/mail/sesaworuban.net/test/output.txt';


Personally I find this missleading. Intuitively I would assume that $outfile
contains the file name of the output file. However it doesn't. It also
contains some wierd additional chevron.

> open (INFILE, $infile) or die "cannot open $infile: $!"; # opens the
> file
> open (OUTFILE, $outfile) or die "cannot open $outfile: $!"; # opens
> the file


And here I am missing the chevron, which would indicate that you are opening
the file for writing. No big deal, it works like you coded it, but a few
month from now it will confuse you and it will cost extra time to figure out
why the chevron is missing here.

> while()


While what? I guess you meant
while (<INFILE>)

> {


Spaces for indentation are cheap, use them liberaly

> chomp;
> $key='',next if /^\s*$/;
> if(/([\w\s]+):(.*)/){
> $key=$1;
> push @{$hash{$key}},$2;
> }
> else
> {
> push @{$hash{$key}},$_ if $key;
> }
> }


No idea what this loop body is supposed to do. It looks way to complicated
to me.
A simple single-line
{ print OUTFILE if (/:/); }
appears to be all you would need according to your spec above. "Copy a line
if it contains a colon sign".

> for(sort keys %hash)
> {
> print OUTFILE "$_ : ".join("\n",@{$hash{$_}})."\n";
> }


Well, why? Your spec doesn't say anything about sorting.

jue



Tad McClellan 02-01-2004 06:57 PM

Re: Extract text from a file and write to another.
 
Sesa Woruban <me@sesaworuban.net> wrote:

> I'm trying to create a
> simple programme that will extract the pertinent lines (only those
> with a : in them) from a plain flat text file (that represents my
> inbox) and write only those files to another text file.



perl -ne 'print if /:/' infile >outfile


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas

Sesa Woruban 02-02-2004 06:36 AM

Re: Extract text from a file and write to another.
 
> If this is a mailbox, you would be better off using one of the Mail::
> modules on CPAN to parse it.


Possibly, and I went to have a look at these modules but I think the
learning curve for those will be even higher than just getting this
simple programme cobbled together... unless you can give me a quick
intro?

Cheers
Sesa


All times are GMT. The time now is 12:44 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.