Beginner: read and print same file

M

Marek Stepanek

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
 
M

Matt Garrish

Marek said:
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
 
M

Matt Garrish

Matt said:
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
 
M

Marek Stepanek

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,


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 :)
 
M

Matt Garrish

[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
 
U

Uri Guttman

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
 
J

John W. Krahn

Marek said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top