Beginner: read and print same file

Discussion in 'Perl Misc' started by Marek Stepanek, Aug 13, 2006.

  1. Hallo happy Perlers,


    I have to bother you once again. I have a script with __DATA__ which will be
    transformed later into a LaTeX Table. Just now I am stuck to insert these
    DATA after a keyword "% begin", but I am not finding the solution.

    Greetings from Munich,


    marek


    My LaTeX-Table "calc_hours_table02.tex" looks like follows:

    \begin{longtable}[c]{| c | c | c | c | c | c | c | c |}

    \hline
    % \caption{table title}\\
    \multicolumn{8}{| c |}{\textbf{TITLE}} \\
    \hline
    & & & \multicolumn{5}{ c |}{\textbf{title}} \\
    \hline
    \textbf{Datum} & \textbf{Umsatz 7\%} & \textbf{Umsatz 16\%} &
    \textbf{Beginn} & \textbf{Pause} & \textbf{Ende} & \textbf{Stunden} &
    \textbf{Km-Gesamt} \\
    \hline
    % begin <--- and here my script should insert the transformed data ...

    \hline
    \hline

    \end



    #!/usr/bin/perl

    use strict;
    use warnings;

    ####global variables########
    my (@lines);
    my ($date);
    ####END global variables####


    #### Files #################
    my $out_file = "calc_hours_table02.tex";
    open OUT, "$out_file" or die "Error! $!\n;";
    ####END Files ##############


    ####Read in and work########
    while (<DATA>)
    {
    chomp;
    next if (/^$/);

    if (/^(\w+, [\d\.]+)/)
    {
    $date = $1;
    }

    if (/^TOTAL/)
    {
    s/TOTAL/"$date"/e;
    push (@lines, $_);
    }
    }
    ####END Read in and work####

    ####Output##################
    while (<OUT>)
    {
    if (/^(% begin)$/)
    {
    s/(% begin)/"$1\n" . join ("\n",@lines)/e; ###And here my problem!
    # print OUT "$1\n";
    # print OUT join ("\n",@lines);
    # print OUT "\n";
    }
    }
    ####END Output##############

    ######Data to read in#######

    __DATA__

    Son, 16.07.2006 37086.40 15445.00 808 19.50 3156.30
    Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
    TOTAL 580.60 324.20 9 0.00 464.70

    Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
    Die, 18.07.2006 37936.50 15929.60 823 19.50 3857.80
    TOTAL 269.50 160.40 6 0.00 236.80

    Die, 18.07.2006 37936.50 15929.60 823 19.50 3857.80
    Mit, 19.07.2006 38147.50 16058.00 827 19.50 4042.80
    TOTAL 211.00 128.40 4 0.00 185.00

    Mit, 19.07.2006 38147.50 16058.00 827 19.50 4042.80
    Don, 20.07.2006 38371.80 16188.60 833 19.50 4247.40
    TOTAL 224.30 130.60 6 0.00 204.60

    Don, 20.07.2006 38371.80 16188.60 833 19.50 4247.40
    Fre, 21.07.2006 38607.70 16252.70 837 19.50 4359.20
    TOTAL 235.90 64.10 4 0.00 111.80 55.00 166.80

    Fre, 21.07.2006 38607.70 16252.70 837 19.50 4359.20
    Sam, 22.07.2006 38752.70 16351.60 844 20.50 4523.90
    TOTAL 145.00 98.90 7 1.00 164.70

    Sam, 22.07.2006 38752.70 16351.60 844 20.50 4523.90
    Son, 23.07.2006 38774.20 16351.60 844 20.50 4526.90
    TOTAL 21.50 0.00 0 0.00 3.00

    Son, 23.07.2006 38774.20 16351.60 844 20.50 4526.90
    Mon, 24.07.2006 39056.90 16499.80 849 20.50 4740.60
    TOTAL 282.70 148.20 5 0.00 213.70

    Mon, 24.07.2006 39056.90 16499.80 849 20.50 4740.60
    Die, 25.07.2006 39249.20 16574.60 853 20.50 4854.60
    TOTAL 192.30 74.80 4 0.00 114.00

    Die, 25.07.2006 39249.20 16574.60 853 20.50 4854.60
    Mit, 26.07.2006 39249.20 16574.60 853 20.50 4854.60
    TOTAL 0.00 0.00 0 0.00 0.00 55.00 55.00

    Mit, 26.07.2006 39249.20 16574.60 853 20.50 4854.60
    Don, 27.07.2006 39720.70 16762.90 864 21.50 5148.70
    TOTAL 471.50 188.30 11 1.00 294.10

    Don, 27.07.2006 39720.70 16762.90 864 21.50 5148.70
    Fre, 28.07.2006 39932.00 16847.60 872 22.00 5289.80
    TOTAL 211.30 84.70 8 0.50 141.10

    Fre, 28.07.2006 39932.00 16847.60 872 22.00 5289.80
    Sam, 29.07.2006 40002.60 16852.90 874 22.00 5307.00
    TOTAL 70.60 5.30 2 0.00 17.20

    Sam, 29.07.2006 40002.60 16852.90 874 22.00 5307.00
    Son, 30.07.2006 40002.60 16852.90 874 22.00 5307.00
    TOTAL 0.00 0.00 0 0.00 0.00

    Son, 30.07.2006 40002.60 16852.90 874 22.00 5307.00
    Mon, 31.07.2006 40224.40 16953.00 884 22.00 5485.40
    TOTAL 221.80 100.10 10 0.00 178.40
    Marek Stepanek, Aug 13, 2006
    #1
    1. Advertising

  2. Marek Stepanek

    Matt Garrish Guest

    Marek Stepanek wrote:

    >
    > Just now I am stuck to insert these
    > DATA after a keyword "% begin", but I am not finding the solution.
    >



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


    Always good.

    > ####global variables########
    > my (@lines);
    > my ($date);


    Not sure why the parens are there, as they just add clutter.

    >
    >
    > #### Files #################
    > my $out_file = "calc_hours_table02.tex";
    > open OUT, "$out_file" or die "Error! $!\n;";


    You've opened OUT for reading, but yet you try and write to it later.
    You're also needlessly quoting $out_file (see perldoc -q quote) and not
    using the three-argument open:

    open my $out, '>>', $outfile or die "Could not open $outfile for
    writing: $!";

    >
    > ####Output##################
    > while (<OUT>)
    > {
    > if (/^(% begin)$/)


    Wasteful to capture in the pattern match just to throw it away. It's
    also wasteful to test a substitution before doing it. You can use the
    if condition to check whether the substitution happened and avoid
    pattern matching first.

    > {
    > s/(% begin)/"$1\n" . join ("\n",@lines)/e; ###And here my problem!


    Considering the print statements that follow this part, I have to think
    you've missed a fundamental concept of reading and writing files. As
    stated above, you didn't open the file in the right mode, but even if
    you had, trying to read it and write to it at the same time cannot be
    done by a simple read. If you can't read the file in and manipulate it
    in memory, you might consider the Tie::File module.

    You could have saved us some time by indicating the error messages you
    got, rather than commenting them out and asking an unrelated question.

    Matt
    Matt Garrish, Aug 13, 2006
    #2
    1. Advertising

  3. Marek Stepanek

    Matt Garrish Guest

    Matt Garrish wrote:

    > Marek Stepanek wrote:
    >
    > >
    > > open OUT, "$out_file" or die "Error! $!\n;";

    >
    > You've opened OUT for reading, but yet you try and write to it later.
    > You're also needlessly quoting $out_file (see perldoc -q quote)


    By which I of course meant "perldoc -q quoting"...

    Matt
    Matt Garrish, Aug 13, 2006
    #3
  4. On 13.08.2006 23:00, in article ,
    "Michele Dondi" <> wrote:

    > On Sun, 13 Aug 2006 20:50:32 +0200, Marek Stepanek <>
    > wrote:
    >
    >> I have to bother you once again. I have a script with __DATA__ which will be
    >> transformed later into a LaTeX Table. Just now I am stuck to insert these
    >> DATA after a keyword "% begin", but I am not finding the solution.

    >
    > Since your actual question seems to have been already addressed... an
    > ad for a relatively unknown, but very nice, piece of software:
    > PerlTeX. Did you try it?
    >
    >
    > Michele



    Thank you Matt and Michele,


    On 13.08.2006 21:15, in article
    , "Matt Garrish"
    <> wrote:

    > open my $out, '>>', $outfile or die "Could not open $outfile for
    > writing: $!";


    I am blushing, but I don't understand this one ! I will read once again
    tomorrow:

    perldoc -f open
    perldoc perlopentut
    perldoc Tie::File

    Just for now I changed Matt's suggestion to:

    my $out_file = "calc_hours_table02.tex";
    # open my $out, '>>', $out_file or die "Could not open $out_file for
    writing: $!"; # how I have to handle "my $out" later in my script?
    open OUT, "+<$out_file" or die "Could not open $out_file for writing: $!";

    which is inserting at the END of my out_file the @lines, instead of
    inserting it AFTER % begin :

    while (<OUT>)
    {
    if (/^% begin$/)
    {
    s/(% begin)/"$1\n" . join ("\n",@lines)/e;
    }
    }

    thank you for your patience


    marek (will be online only tomorrow evening)

    ps: Michele, looking forward discovering PerlTeX tomorrow :)
    Marek Stepanek, Aug 13, 2006
    #4
  5. Marek Stepanek

    Matt Garrish Guest

    Marek Stepanek wrote:

    > Matt Garrish wrote:
    > >

    >
    > > open my $out, '>>', $outfile or die "Could not open $outfile for
    > > writing: $!";


    [please don't intersperse your questions in quoted text]

    > # how I have to handle "my $out" later in my script?
    >


    You can use a scalar to hold the filehandle:

    print $out "I'm printing!";

    There are a number of benfits to using a scalar, but rather than give
    you an incomplete explanation I'll leave you to read up on it.

    > open OUT, "+<$out_file" or die "Could not open $out_file for writing: $!";


    > which is inserting at the END of my out_file the @lines, instead of
    > inserting it AFTER % begin


    If you want to do an in-place edit then you can use '+<', but not the
    way you're trying to read/manipulate the file. You'd need to be using
    syswrite/sysseek, and that's not for the faint of heart. Have a look at
    perlopentut. It will explain the behaviour you're experiencing.

    Again, though, the normal solutions are to slurp the file in,
    manipulate it and write it back out or use Tie::File.

    Matt
    Matt Garrish, Aug 13, 2006
    #5
  6. Marek Stepanek

    Uri Guttman Guest

    >>>>> "MG" == Matt Garrish <> writes:

    MG> If you want to do an in-place edit then you can use '+<', but not the
    MG> way you're trying to read/manipulate the file. You'd need to be using
    MG> syswrite/sysseek, and that's not for the faint of heart. Have a look at
    MG> perlopentut. It will explain the behaviour you're experiencing.

    MG> Again, though, the normal solutions are to slurp the file in,
    MG> manipulate it and write it back out or use Tie::File.

    a future feature of File::Slurp will be the subs edit_file and
    edit_file_lines. they will slurp in a file, call a code ref you pass in
    with either the file or each line in $_, then write back out $_ to the
    same file.

    dunno when this will be done. it won't be much module code and most of
    the work will be in option handling and writing tests. volunteers are
    welcome to help! :)

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Aug 14, 2006
    #6
  7. Marek Stepanek wrote:
    >
    > I have to bother you once again. I have a script with __DATA__ which will be
    > transformed later into a LaTeX Table. Just now I am stuck to insert these
    > DATA after a keyword "% begin", but I am not finding the solution.
    >
    >
    > My LaTeX-Table "calc_hours_table02.tex" looks like follows:
    >
    > \begin{longtable}[c]{| c | c | c | c | c | c | c | c |}
    >
    > \hline
    > % \caption{table title}\\
    > \multicolumn{8}{| c |}{\textbf{TITLE}} \\
    > \hline
    > & & & \multicolumn{5}{ c |}{\textbf{title}} \\
    > \hline
    > \textbf{Datum} & \textbf{Umsatz 7\%} & \textbf{Umsatz 16\%} &
    > \textbf{Beginn} & \textbf{Pause} & \textbf{Ende} & \textbf{Stunden} &
    > \textbf{Km-Gesamt} \\
    > \hline
    > % begin <--- and here my script should insert the transformed data ...
    >
    > \hline
    > \hline
    >
    > \end
    >
    >
    >
    > #!/usr/bin/perl
    >
    > use strict;
    > use warnings;
    >
    > ####global variables########
    > my (@lines);
    > my ($date);
    > ####END global variables####
    >
    >
    > #### Files #################
    > my $out_file = "calc_hours_table02.tex";
    > open OUT, "$out_file" or die "Error! $!\n;";
    > ####END Files ##############
    >
    >
    > ####Read in and work########
    > while (<DATA>)
    > {
    > chomp;
    > next if (/^$/);
    >
    > if (/^(\w+, [\d\.]+)/)
    > {
    > $date = $1;
    > }
    >
    > if (/^TOTAL/)
    > {
    > s/TOTAL/"$date"/e;
    > push (@lines, $_);
    > }
    > }
    > ####END Read in and work####
    >
    > ####Output##################
    > while (<OUT>)
    > {
    > if (/^(% begin)$/)
    > {
    > s/(% begin)/"$1\n" . join ("\n",@lines)/e; ###And here my problem!
    > # print OUT "$1\n";
    > # print OUT join ("\n",@lines);
    > # print OUT "\n";
    > }
    > }
    > ####END Output##############
    >
    > ######Data to read in#######
    >
    > __DATA__
    >
    > Son, 16.07.2006 37086.40 15445.00 808 19.50 3156.30
    > Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
    > TOTAL 580.60 324.20 9 0.00 464.70
    >
    > Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
    > Die, 18.07.2006 37936.50 15929.60 823 19.50 3857.80
    > TOTAL 269.50 160.40 6 0.00 236.80


    [snip]

    After reading the posts on this thread it looks like you want something like:


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

    #### Files #################
    my $out_file = 'calc_hours_table02.tex';
    ####END Files ##############

    ####Read in and work########
    my ( $date, $lines );
    while ( <DATA> ) {
    /^(\w+, +[\d.]+)/ and $date = $1;
    s/^TOTAL// and $lines .= "$date$_";
    }
    ####END Read in and work####


    ####Output##################
    ( $^I, @ARGV ) = ( '', $out_file );
    while ( <> ) {
    s/^(% begin\n)/$1$lines/;
    print;
    }
    ####END Output##############

    ######Data to read in#######

    __DATA__

    Son, 16.07.2006 37086.40 15445.00 808 19.50 3156.30
    Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
    TOTAL 580.60 324.20 9 0.00 464.70

    Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
    Die, 18.07.2006 37936.50 15929.60 823 19.50 3857.80
    TOTAL 269.50 160.40 6 0.00 236.80

    [snip]



    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Aug 14, 2006
    #7
    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. keto
    Replies:
    0
    Views:
    897
  2. David Cournapeau

    print a vs print '%s' % a vs print '%f' a

    David Cournapeau, Dec 30, 2008, in forum: Python
    Replies:
    0
    Views:
    335
    David Cournapeau
    Dec 30, 2008
  3. Johnathan Smith

    read file and print contents - beginner

    Johnathan Smith, Dec 3, 2007, in forum: Ruby
    Replies:
    2
    Views:
    92
    Andrei Maxim
    Dec 3, 2007
  4. Replies:
    3
    Views:
    105
    Brian Candler
    Dec 25, 2008
  5. Alex Dowad
    Replies:
    4
    Views:
    256
    Michel Demazure
    May 1, 2010
Loading...

Share This Page