new lines in the way

Discussion in 'Perl Misc' started by new2perl@gmail.com, Jul 19, 2007.

  1. Guest

    Hi,

    I am trying to parse a text file that looks like this:

    __
    VAR1=15
    VAR2=16
    VAR=17

    FIRSTJOKE=this is my first joke. its isnt that funny but its still
    pretty good bla hbls dfd fsdf dsf sdfsd sd fdssd sdfdsf
    dsfdsfsdsdfsfsd

    SECONDJOKE=fdsf sdfdsf sdfdsfsdfdsfdsfdsfderew
    rweeeeeeeeeeeeeeeeeeeeeeeer2 wr ewre rewr er ewewrrewrew rewrewrew
    ewrew ewr ewr er ewr ewr er ewr we rew ew
    rewrewrewrewrewrererewrewrewrewrewrewrewrwerewrererewreerewrewrerererererer

    THIRDJOKE=notfunny
    ---

    My code is like this:

    #!/bin/perl

    #$/=undef;

    $conffile = "/myarea/myconfigfile";

    #read in config variables
    open ( CONFIGFILE, "< $conffile" ) || die "Can't open email template:
    $conffile \n";

    while ( <CONFIGFILE> ) {
    chop;
    if (/.*=.*/) {
    ($ConfigVar, $Congif_value) = split (/=/);
    $ConfigValues{$ConfigVar}=$Congif_value;
    }

    }
    close CONFIGFILE,


    while ( ($k,$v) = each %ConfigValues ) {
    print "$k => $v\n";
    }


    # It only prints out the first line of each joke. I played around
    with $/ but not working.
    # I understand that $/ is set to new line by default. So this explains
    why I only get
    # the first line of each joke.
    # There must be a simple way to fix this? I appreciate any feedback.
    Bob


    while ( ($k,$v) = each %ConfigValues ) {
    print "$k => $v\n";
    }

    Output:

    SECONDJOKE => fdsf sdfdsf sdfdsfsdfdsfdsfdsfderew
    rweeeeeeeeeeeeeeeeeeeeeeeer2 wr ewre
    THIRDJOKE => notfunny
    VAR1 => 15
    VAR => 17
    VAR2 => 16
    FIRSTJOKE => this is my first joke. its isnt that funny but its still
    pretty good bla
    , Jul 19, 2007
    #1
    1. Advertising

  2. Mirco Wahab Guest

    wrote:
    > I am trying to parse a text file that looks like this:
    > VAR1=15
    > VAR2=16
    > VAR=17
    >
    > FIRSTJOKE=this is my first joke. its isnt that funny but its still
    > pretty good bla hbls dfd fsdf dsf sdfsd sd fdssd sdfdsf
    > dsfdsfsdsdfsfsd


    ....
    ....

    > # It only prints out the first line of each joke. I played around
    > with $/ but not working.
    > # I understand that $/ is set to new line by default. So this explains
    > why I only get
    > # the first line of each joke.
    > # There must be a simple way to fix this? I appreciate any feedback.


    This is not the real reason. You cant read 'line by line' because
    your data items have more than one line. *If* you put an *empty*
    new line behind each item, like

    VAR1=15

    VAR2=16

    VAR=17

    you could read the file in 'paragraph' mode like:

    (pseudocode:)

    $/ = ''; # set para mode
    while( <CONFIGFILE> ) {
    ($ConfigVar, $Congif_value) = split /=/;
    $ConfigValues{$ConfigVar} = $Congif_value;
    }

    and thats it. Otherwise (no empty line between items),
    as your example suggests, you have to read in 'slurp'
    mode (read the while file into one block), like:


    ...
    my $fname= 'myconfigfile';

    open( my $fh, '<', $fname ) or die "Can't read $!";
    my $content;
    { local $/; $content = <$fh> }; # read in 'slurp' mode
    close $fh;
    ...

    I modified the style of the statements a blittle bit
    to match a more comprehensive Perl style. The whole
    file would now reside in $content, lets extract
    it in one stroke (by regex).

    ...
    my $reg = qr{
    ^(\w+)\s*=\s* # key follows ^
    (.+ # complete text until $ (/m)
    (?:\n [^=]* $)* # if available, take more lines w/out '='
    ) # (note the '$' anchor!)
    }mx;
    ...

    The regex has a second part in the second
    (values) capture group: (?:\n [^=]* $)*
    which reads entire lines if no '=' is
    found in there.

    Lets apply it:
    ...
    my %Config = $content =~ /$reg/g;
    ...

    You can print it as you used to do:

    ...
    while ( my ($k,$v) = each %Config ) {
    print "$k => $v\n\n";
    }
    ...

    Regards

    M.
    Mirco Wahab, Jul 19, 2007
    #2
    1. Advertising

  3. -berlin.de Guest

    <> wrote in comp.lang.perl.misc:
    > Hi,
    >
    > I am trying to parse a text file that looks like this:
    >
    > __
    > VAR1=15
    > VAR2=16
    > VAR=17
    >
    > FIRSTJOKE=this is my first joke. its isnt that funny but its still
    > pretty good bla hbls dfd fsdf dsf sdfsd sd fdssd sdfdsf
    > dsfdsfsdsdfsfsd
    >
    > SECONDJOKE=fdsf sdfdsf sdfdsfsdfdsfdsfdsfderew
    > rweeeeeeeeeeeeeeeeeeeeeeeer2 wr ewre rewr er ewewrrewrew rewrewrew
    > ewrew ewr ewr er ewr ewr er ewr we rew ew
    > rewrewrewrewrewrererewrewrewrewrewrewrewrwerewrererewreerewrewrerererererer
    >
    > THIRDJOKE=notfunny
    > ---
    >
    > My code is like this:
    >
    > #!/bin/perl


    No warnings? No strict?

    > #$/=undef;
    >
    > $conffile = "/myarea/myconfigfile";
    >
    > #read in config variables
    > open ( CONFIGFILE, "< $conffile" ) || die "Can't open email template:
    > $conffile \n";
    >
    > while ( <CONFIGFILE> ) {
    > chop;
    > if (/.*=.*/) {
    > ($ConfigVar, $Congif_value) = split (/=/);
    > $ConfigValues{$ConfigVar}=$Congif_value;
    > }
    >
    > }
    > close CONFIGFILE,

    ^
    The comma is an error, it should be a semicolon. This is not the code
    you ran. Don't re-type code, copy and paste it.

    > while ( ($k,$v) = each %ConfigValues ) {
    > print "$k => $v\n";
    > }
    >
    >
    > # It only prints out the first line of each joke.


    Sure. You are only printing lines with a "=" in them. What did you
    expect.

    > I played around
    > with $/ but not working.


    "Not working" is no useful error description. What exactly have
    you tried?

    Your file format is irregular. Some of the assignments are followed
    by an empty line (the JOKEs), others aren't (the VARs). So paragraph
    mode won't help you much.

    > # I understand that $/ is set to new line by default. So this explains
    > why I only get
    > # the first line of each joke.
    > # There must be a simple way to fix this? I appreciate any feedback.


    The unsuitable format doesn't allow for a really simple way. You'll
    have to scan the file, looking for the next line with a "=" in it while
    collecting other lines to form the value of the previous assignment.
    You can only store away one key/value pair when you have seen the next
    one. The last assignment must be treated outside the loop.

    my %ConfigValues;
    my ( $ConfigVar, $ConfigValue);
    while ( <DATA> ) {
    chop;
    if (/.*=.*/) {
    $ConfigValues{$ConfigVar} = $ConfigValue if defined $ConfigVar;
    ($ConfigVar, $ConfigValue) = split (/=/);
    } else {
    $ConfigValue .= $_;
    }

    }
    $ConfigValues{$ConfigVar} = $ConfigValue if defined $ConfigVar;
    close CONFIGFILE,

    while ( my ($k,$v) = each %ConfigValues ) {
    print "$k => $v\n";
    }

    __END__
    VAR1=15
    VAR2=16
    VAR=17

    FIRSTJOKE=this is my first joke. its isnt that funny but its still
    pretty good bla hbls dfd fsdf dsf sdfsd sd fdssd sdfdsf
    dsfdsfsdsdfsfsd

    SECONDJOKE=fdsf sdfdsf sdfdsfsdfdsfdsfdsfderew
    rweeeeeeeeeeeeeeeeeeeeeeeer2 wr ewre rewr er ewewrrewrew rewrewrew
    ewrew ewr ewr er ewr ewr er ewr we rew ew
    rewrewrewrewrewrererewrewrewrewrewrewrewrwerewrererewreerewrewrerererererer

    THIRDJOKE=notfunny

    Anno
    -berlin.de, Jul 19, 2007
    #3
  4. -berlin.de Guest

    <> wrote in comp.lang.perl.misc:
    > Hi,
    >
    > I am trying to parse a text file that looks like this:
    >
    > __
    > VAR1=15
    > VAR2=16
    > VAR=17
    >
    > FIRSTJOKE=this is my first joke. its isnt that funny but its still
    > pretty good bla hbls dfd fsdf dsf sdfsd sd fdssd sdfdsf
    > dsfdsfsdsdfsfsd
    >
    > SECONDJOKE=fdsf sdfdsf sdfdsfsdfdsfdsfdsfderew
    > rweeeeeeeeeeeeeeeeeeeeeeeer2 wr ewre rewr er ewewrrewrew rewrewrew
    > ewrew ewr ewr er ewr ewr er ewr we rew ew
    > rewrewrewrewrewrererewrewrewrewrewrewrewrwerewrererewreerewrewrerererererer
    >
    > THIRDJOKE=notfunny
    > ---
    >
    > My code is like this:
    >
    > #!/bin/perl


    No warnings? No strict?

    > #$/=undef;
    >
    > $conffile = "/myarea/myconfigfile";
    >
    > #read in config variables
    > open ( CONFIGFILE, "< $conffile" ) || die "Can't open email template:
    > $conffile \n";
    >
    > while ( <CONFIGFILE> ) {
    > chop;
    > if (/.*=.*/) {
    > ($ConfigVar, $Congif_value) = split (/=/);
    > $ConfigValues{$ConfigVar}=$Congif_value;
    > }
    >
    > }
    > close CONFIGFILE,

    ^
    The comma is an error, it should be a semicolon. This is not the code
    you ran. Don't re-type code, copy and paste it.

    > while ( ($k,$v) = each %ConfigValues ) {
    > print "$k => $v\n";
    > }
    >
    >
    > # It only prints out the first line of each joke.


    Sure. You are only printing lines with a "=" in them. What did you
    expect?

    > I played around
    > with $/ but not working.


    "Not working" is no useful error description. What exactly have
    you tried?

    Your file format is irregular. Some of the assignments are followed
    by an empty line (the JOKEs), others aren't (the VARs). So paragraph
    mode won't help you much.

    > # I understand that $/ is set to new line by default. So this explains
    > why I only get
    > # the first line of each joke.
    > # There must be a simple way to fix this? I appreciate any feedback.


    The unsuitable format doesn't allow for a really simple way. You'll
    have to scan the file, looking for the next line with a "=" in it while
    collecting other lines to form the value of the previous assignment.
    You can only store away one key/value pair when you have seen the next
    one. The last assignment must be treated outside the loop.

    my %ConfigValues;
    my ( $ConfigVar, $ConfigValue);
    while ( <DATA> ) {
    chop;
    if (/.*=.*/) {
    $ConfigValues{$ConfigVar} = $ConfigValue if defined $ConfigVar;
    ($ConfigVar, $ConfigValue) = split (/=/);
    } else {
    $ConfigValue .= $_;
    }

    }
    $ConfigValues{$ConfigVar} = $ConfigValue if defined $ConfigVar;
    close CONFIGFILE,

    while ( my ($k,$v) = each %ConfigValues ) {
    print "$k => $v\n";
    }

    __END__
    VAR1=15
    VAR2=16
    VAR=17

    FIRSTJOKE=this is my first joke. its isnt that funny but its still
    pretty good bla hbls dfd fsdf dsf sdfsd sd fdssd sdfdsf
    dsfdsfsdsdfsfsd

    SECONDJOKE=fdsf sdfdsf sdfdsfsdfdsfdsfdsfderew
    rweeeeeeeeeeeeeeeeeeeeeeeer2 wr ewre rewr er ewewrrewrew rewrewrew
    ewrew ewr ewr er ewr ewr er ewr we rew ew
    rewrewrewrewrewrererewrewrewrewrewrewrewrwerewrererewreerewrewrerererererer

    THIRDJOKE=notfunny

    Anno
    -berlin.de, Jul 19, 2007
    #4
  5. On Thu, 19 Jul 2007 02:11:27 -0000, wrote:

    ># It only prints out the first line of each joke. I played around
    >with $/ but not working.
    ># I understand that $/ is set to new line by default. So this explains
    >why I only get
    ># the first line of each joke.
    ># There must be a simple way to fix this? I appreciate any feedback.
    >Bob


    If you know $/, that is you've read

    perldoc perlvar

    then you should know that what you'ere after is ''.


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Jul 19, 2007
    #5
  6. Guest

    On Jul 19, 7:30 am, Michele Dondi <> wrote:
    > On Thu, 19 Jul 2007 02:11:27 -0000, wrote:
    > ># It only prints out the first line of each joke. I played around
    > >with $/ but not working.
    > ># I understand that $/ is set to new line by default. So this explains
    > >why I only get
    > ># the first line of each joke.
    > ># There must be a simple way to fix this? I appreciate any feedback.
    > >Bob

    >
    > If you know $/, that is you've read
    >
    > perldoc perlvar
    >
    > then you should know that what you'ere after is ''.
    >
    > Michele
    > --
    > {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    > (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    > .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    > 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,



    Thanks everyone. I got it working. Thanks for your great advice.
    Bob
    , Jul 20, 2007
    #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. Jack
    Replies:
    9
    Views:
    2,639
  2. Joe Wright
    Replies:
    0
    Views:
    500
    Joe Wright
    Jul 27, 2003
  3. lovecreatesbeauty

    How to know two lines are a pare parallel lines

    lovecreatesbeauty, Apr 27, 2006, in forum: C Programming
    Replies:
    11
    Views:
    642
    Old Wolf
    Apr 28, 2006
  4. Replies:
    1
    Views:
    439
    Jonathan Mcdougall
    Dec 6, 2005
  5. Murali
    Replies:
    2
    Views:
    544
    Jerry Coffin
    Mar 9, 2006
Loading...

Share This Page