Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Works fine on one file, but not on many

Reply
Thread Tools

Works fine on one file, but not on many

 
 
beartiger@gmail.com
Guest
Posts: n/a
 
      10-09-2005
Can anyone tell me why the folling script works on one file but not on
glob(*.html)?

The script is designed to take the following line:

<filestatus owner="jeh" status="1"/>

Strip out the "status" value and then translate it into a string that
appears to the user at the bottom of the file.

When I run the script in glob mode in a dir of .html files, "$stat" is
filled with the entire contents of each file [!]. When I run it on a
single file, "$stat" is correctly filled only with the status value and
the script runs as intended and correctly updates the file.

======================CODE STARTS============================

use strict;
use warnings;



my @files;

if ($ARGV[0])
{
@files= $ARGV[0];
} else
{
@files=glob('*.html');
}

my $stat;


foreach my $file (@files)
{
# first get the file's status

#LOAD
open (HTM, "$file") || die("Error
Reading File: $file $!");
while(<HTM>)
{
if(m/filestatus/)
{
s/.*<filestatus.*?status=\"(\d)\".*?>.*/$1/g;
$stat=$_;
$_="";
}
}
close (HTM) || die("Error
Closing File: $file $!");


# then, based on the code, update the bottom line


open (IN, "$file") || die("Error
Reading File: $file $!");
undef $/; my $remthis= <IN>;
close (IN) || die("Error
Closing File: $file $!");

#CHANGE

if ($stat==0) {$remthis=~ s/.*?<.html>/<font
color=#CCCCCC>Placeholder<\/font><\/html>/g;}
if ($stat==1) {$remthis=~ s/.*?<.html>/<font
color=#CCCCCC>First draft<\/font><\/html>/g;}
if ($stat==2) {$remthis=~ s/.*?<.html>/<font
color=#CCCCCC>Peer Reviewed<\/font><\/html>/g;}
if ($stat==3) {$remthis=~ s/.*?<.html>/<font
color=#CCCCCC>SME Reviewed<\/font><\/html>/g;}
if ($stat==4) {$remthis=~ s/.*?<.html>/<font
color=#CCCCCC>Final draft<\/font><\/html>/g;}

#WRITE
open (OUT, ">$file") || die("Error
Writing File: $file $!");
print OUT $remthis;
close (OUT) || die("Error
Closing File: $file $!");
}

========================CODE ENDS===========================


Many thanks in advance,
John

 
Reply With Quote
 
 
 
 
Matt Garrish
Guest
Posts: n/a
 
      10-09-2005

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> Can anyone tell me why the folling script works on one file but not on
> glob(*.html)?
>
> The script is designed to take the following line:
>
> <filestatus owner="jeh" status="1"/>
>
> Strip out the "status" value and then translate it into a string that
> appears to the user at the bottom of the file.
>
> When I run the script in glob mode in a dir of .html files, "$stat" is
> filled with the entire contents of each file [!]. When I run it on a
> single file, "$stat" is correctly filled only with the status value and
> the script runs as intended and correctly updates the file.
>


You're doing a variety of bad things in your code. For instance, you undef
$/ the first time through the loop, which means it will be undefined for the
rest of your script (local $/ = undef. You're needlessly reading the file
twice. You use stat globally, so it doesn't matter if a file matches as it
will automatically get the last value of stat if it doesn't. You quote
variables that don't need quoting. You are doing case-sensitive matches and
not specifying the /s modifier after slurping the files, which may or may
not explain why only some files work. I'm also not sure why you have
"<.html>" on one side of your final substitution and "<\/html>" on the
other, but regardless you're blowing away everything in the file in those
final substitutions.

Anyway, see if the following does what you want:

use strict;
use warnings;

my @files;

if (@ARGV) {
push @files, $ARGV[0];
}
else {
@files=glob('*.html');
}

foreach my $file (@files) {

my $filecontent;

{
open(my $in, '<', $file) or die "Error Reading $file: $!";
local $/ = undef;
$filecontent = <$in>;
close($in) or die "Error Closing $file: $!";
}

my $stat;

if ($filecontent =~ m/<filestatus[^>]+status="(\d)"/is) {
$stat=$1;
}

else {
print "Error: no stat value for $file. Unable to process.\n";
next;
}

if ($stat==0) {$filecontent=~ s|</html>|<font
color=#CCCCCC>Placeholder</font></html>|gis;}
elsif ($stat==1) {$filecontent=~ s|</html>|<font color=#CCCCCC>First
draft</font></html>|gis;}
elsif ($stat==2) {$filecontent=~ s|</html>|<font color=#CCCCCC>Peer
Reviewed</font></html>|gis;}
elsif ($stat==3) {$filecontent=~ s|</html>|<font color=#CCCCCC>SME
Reviewed</font></html>|gis;}
elsif ($stat==4) {$filecontent=~ s|</html>|<font color=#CCCCCC>Final
draft</font></html>|gis;}

open(my $out, '>', $file) or die "Error Writing $file: $!";
print $out $filecontent;
close($out) or die "Error Closing $file: $!";

}


 
Reply With Quote
 
 
 
 
John W. Krahn
Guest
Posts: n/a
 
      10-09-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Can anyone tell me why the folling script works on one file but not on
> glob(*.html)?
>
> The script is designed to take the following line:
>
> <filestatus owner="jeh" status="1"/>
>
> Strip out the "status" value and then translate it into a string that
> appears to the user at the bottom of the file.
>
> When I run the script in glob mode in a dir of .html files, "$stat" is
> filled with the entire contents of each file [!]. When I run it on a
> single file, "$stat" is correctly filled only with the status value and
> the script runs as intended and correctly updates the file.


You are changing the value of $/ which is a global variable. Change:

undef $/; my $remthis= <IN>;

To:

my $remthis = do { local $/; <IN> };


John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
Matt Garrish
Guest
Posts: n/a
 
      10-09-2005

"Matt Garrish" <(E-Mail Removed)> wrote in message
news:Mfb2f.210$(E-Mail Removed)...
>
>
> if ($stat==0) {$filecontent=~ s|</html>|<font
> color=#CCCCCC>Placeholder</font></html>|gis;}
> elsif ($stat==1) {$filecontent=~ s|</html>|<font color=#CCCCCC>First
> draft</font></html>|gis;}
> elsif ($stat==2) {$filecontent=~ s|</html>|<font color=#CCCCCC>Peer
> Reviewed</font></html>|gis;}
> elsif ($stat==3) {$filecontent=~ s|</html>|<font color=#CCCCCC>SME
> Reviewed</font></html>|gis;}
> elsif ($stat==4) {$filecontent=~ s|</html>|<font color=#CCCCCC>Final
> draft</font></html>|gis;}
>


Oops, I forgot to remove the /g modifier you added to the last substitution.
It's pointless unless there really are multiple closing html tags in your
files.

Matt


 
Reply With Quote
 
beartiger@gmail.com
Guest
Posts: n/a
 
      10-09-2005
Matt Garrish wrote:
<snip excellent response>

Matt, many many thanks. Your revised code worked better, but appended
the string to the existing string in the file a la:

<font color=#CCCCCC>Placeholder</font><font
color=#CCCCCC>Placeholder</font></html>

Neverthess, I (hope I) learned some things from your response.

The revision below works well. I found that making stat a string rather
than int was smarter, since the author could put, say, "A" in the
status value.

I hope I didn't repeat any of my earlier mistakes in this one, or
introduce new ones:

==========================CODE BEGINS===========================

use strict;
use warnings;

my @files;
my @lines;

if (@ARGV) { push @files, $ARGV[0]; } else { @files=glob('*.html'); }

foreach my $file (@files) {

{
open(my $in, '<', $file) or die "Error Reading $file: $!";

my $stat="";

while(<$in>)
{
if (/<filestatus[^>]+status="(\d)"/is) { $stat=$1; }


if($stat=~m/0/) {s|^<font
color=#CCCCCC>.*?</font></html>|<font
color=#CCCCCC>Placeholder</font></html>|is; }
elsif($stat=~m/1/) {s|^<font
color=#CCCCCC>.*?</font></html>|<font color=#CCCCCC>First
draft</font></html>|is; }
elsif($stat=~m/2/) {s|^<font
color=#CCCCCC>.*?</font></html>|<font color=#CCCCCC>Peer
reviewed</font></html>|is;}
elsif($stat=~m/3/) {s|^<font
color=#CCCCCC>.*?</font></html>|<font color=#CCCCCC>SME
reveiwed</font></html>|is; }
elsif($stat=~m/4/) {s|^<font
color=#CCCCCC>.*?</font></html>|<font color=#CCCCCC>Final
draft</font></html>|is; }
else
{s|^<font color=#CCCCCC>.*?</font></html>|<font
color=#CCCCCC>BAD CODE: look at filestatus tags in
source</font></html>|is;}

push(@lines,$_);
}

close($in) or die "Error Closing $file: $!";
}


open(my $out, '>', $file) or die "Error Writing $file: $!";
print $out @lines;
close($out) or die "Error Closing $file: $!";

}

==========================CODE ENDS===========================

 
Reply With Quote
 
beartiger@gmail.com
Guest
Posts: n/a
 
      10-09-2005
John W. Krahn wrote:
<snip>
> You are changing the value of $/ which is a global variable. Change:
>
> undef $/; my $remthis= <IN>;
>
> To:
>
> my $remthis = do { local $/; <IN> };


Thanks. I decided not to undef $/ at all. Is it a little risky?


J

 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      10-09-2005
(E-Mail Removed) wrote:
> John W. Krahn wrote:
> <snip>
>>You are changing the value of $/ which is a global variable. Change:
>>
>> undef $/; my $remthis= <IN>;
>>
>>To:
>>
>> my $remthis = do { local $/; <IN> };

>
> Thanks. I decided not to undef $/ at all. Is it a little risky?


It could be if the expression |^<font color=#CCCCCC>.*?</font></html>| is
trying to match a multi-line string because the default is to put only one
line in the $_ variable. This may work better for you (UNTESTED):


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

use Fatal qw( :void open print close );

@ARGV or @ARGV = glob '*.html';

# Set in-place edit to create backups and unset Input Record Separator
local ( $^I, $/ ) = '.bak';

my %stats = (
0 => 'Placeholder',
1 => 'First draft',
2 => 'Peer reviewed',
3 => 'SME reveiwed',
4 => 'Final draft',
);

my $stat = '';

# In-place edit files in @ARGV
while ( <> ) {
if ( /<filestatus[^>]+?status="(\d)"/i ) {
$stat = exists $stats{ $1 }
? $stats{ $1 }
: 'BAD CODE: look at filestatus tags in source'
}

s|(?<=^<font color=#CCCCCC>).*?(?=</font></html>)|$stat|isg;

print;

if ( eof ) {
$stat = '';
close ARGV;
}
}

__END__




John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
Sherm Pendley
Guest
Posts: n/a
 
      10-10-2005
Purl Gurl <(E-Mail Removed)> writes:

> (E-Mail Removed) wrote:
>
> > <filestatus owner="jeh" status="1"/>

>
> Your "/>" at the end of your example. Is that a mistake?


Impossible to tell without seeing the surrounding context. It *is* legal
"shorthand" for an empty XML element - it's equivalent to:

<filestatus owner="jeh" status="1"></filestatus>

On the other hand, if there's a DTD that doesn't allow the filestatus
element to be empty, or if there's a closing tag in addition to the
standalone tag shown above, then the XML is bogus.

sherm--

--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Web Services on a Windows 2000 IIS 5.x ASP.Net 1.1 works fine but not on 2003 Mufasa ASP .Net 2 04-19-2007 08:09 PM
Autopostback and Smartnavigation works fine, but not for me catweezle2010 ASP .Net 0 01-26-2006 11:28 AM
Page works fine with internal webserver but not on IIS Eric ASP .Net 5 12-05-2005 08:20 PM
Java Webpage Works Fine On One Machine But Not Another Larry R Harrison Jr Javascript 1 08-20-2004 01:41 PM
Java Webpage Works Fine on One Machine But Not Another Larry R Harrison Jr Javascript 0 08-20-2004 03:14 AM



Advertisments