Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Can't Open Files 1

Status
Not open for further replies.

tbohon

Programmer
Apr 20, 2000
293
US
Have a requirement to open every file found in a specific directory, perform a simple substitution, and write it back out. Will do the output writing routine later but right now the routine below keeps dying when trying to open the first file in the array. I've checked and the files - there are 6 of them - contain data and are chmod-ed to 644. User who created the files is the same as the owner of this Perl script.

Here's the script:

Code:
#!/bin/perl

$source_dir = "/interface/ftp/files_in";
$target_dir = "/interface/ftp/files_out";

### get list of files to be processed into filenames array

opendir( DIR, $source_dir ) || die "Can't open source directory!\n";

local( @filenames ) = readdir( DIR );

closedir( DIR ) || die "Can't close source directory!\n";

### process each file, one at a time, except '.' and '..' files

foreach $myfile ( @filenames )
{
  print "File being processed is $myfile\n";

  if ( $myfile eq "." || $myfile eq "..") { print "IGNORED\n"; next };

  unless (open(INFILE, $source_dir/$myfile))
  {
    die ("Input file $source_dir/$myfile cannot be opened\n");
  }

    $line = <INFILE>;  [COLOR=red]###NEVER GETS HERE!!!!![/color]

    while ($line ne "")
    {
      if (substr($line,1,3) eq "fac")    ### should be on line 3 of the file
      {
        $facility = substr($line,5,1);
        print "Facility code               :  $facility\n";
      }

      if (substr($line,1,15) eq "report_subtitle")    ### should be on line 8 of the file
      {
        print "Original report subtitle line:  $line\n";
        $rs = substr($line,17);
        $line = "%report_subtitle%" . $facility . $rs;
        print "Changed report subtitle line :  $line\n";
      }


      }

      $line = <INFILE>;
  }

  close INFILE;
}

Would appreciate assistance in figuring this one out - it doesn't make sense to me.

Tnx.

Tom

"My mind is like a steel whatchamacallit ...
 
is this school/course work?

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
This line is your culprit:

Code:
  unless (open(INFILE, $source_dir/$myfile))

- Miller
 
Kevin, no it's not school/course work ... I'm an experienced (41 years) professional IT programmer/analyst who works with Perl, Korn Shell and HL7 interfaces in a multi-hospital environment. This is for an ftp process I've been asked to write (literally) overnight.

Miller - can you explain? I originally didn't have that statement in the script but, when it didn't process/display anything whatsoever, put it in to check out what was going on. Easy to take out and will do that - just curious why it doesn't work. Bear in mind, I've been here x10 hours now and my mind is oatmeal so I'll probably be embarassed by the simplicity of the reason ... in 41+ years in this business, I've learned to be really, really humble so I'll survie but ... :)

Tnx.

"My mind is like a steel whatchamacallit ...
 
Miller:

Substituted the following (in red) for the offending line you identified and it processes each file but never opens or modifies them ... ?

Code:
[COLOR=red]if (open(INFILE, $source_dir/$myfile))[/color]
  {

    $line = <INFILE>;

    while ($line ne "")
    {
      if (substr($line,1,3) eq "fac")    ### should be on line 3

Tnx in advance.

Tom

"My mind is like a steel whatchamacallit ...
 
Code:
unless (open(INFILE, "$source_dir/$myfile"))

Note the quotes.

- Miller
 
PS, applying some refactoring, I would change your code to the following:

Code:
[gray]#!/bin/perl[/gray]

[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$source_dir[/blue] = [red]"[/red][purple]/interface/ftp/files_in[/purple][red]"[/red][red];[/red]
[black][b]my[/b][/black] [blue]$target_dir[/blue] = [red]"[/red][purple]/interface/ftp/files_out[/purple][red]"[/red][red];[/red]

[gray][i]### get list of files to be processed into filenames array[/i][/gray]

[url=http://perldoc.perl.org/functions/opendir.html][black][b]opendir[/b][/black][/url][red]([/red]DIR, [blue]$source_dir[/blue][red])[/red] or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]Can't open [blue]$source_dir[/blue]: [blue]$![/blue][/purple][red]"[/red][red];[/red]
[olive][b]while[/b][/olive] [red]([/red]<DIR>[red])[/red] [red]{[/red]
	[olive][b]next[/b][/olive] [olive][b]if[/b][/olive] [red]/[/red][purple]^[purple][b]\.[/b][/purple][purple][b]\.[/b][/purple]?$[/purple][red]/[/red][red];[/red]

	[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple]File being processed is [blue]$_[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
	[black][b]my[/b][/black] [blue]$infile[/blue] = [red]"[/red][purple][blue]$source_dir[/blue]/[blue]$_[/blue][/purple][red]"[/red][red];[/red]
	[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url][red]([/red]INFILE, [blue]$infile[/blue][red])[/red] or [black][b]die[/b][/black] [red]"[/red][purple]Can't open [blue]$infile[/blue]: [blue]$![/blue][/purple][red]"[/red][red];[/red]

	[olive][b]while[/b][/olive] [red]([/red]<INFILE>[red])[/red] [red]{[/red]
		[black][b]my[/b][/black] [blue]$line[/blue] = [blue]$_[/blue][red];[/red]

		[gray][i]### should be on line 3 of the file[/i][/gray]
		[olive][b]if[/b][/olive] [red]([/red][url=http://perldoc.perl.org/functions/substr.html][black][b]substr[/b][/black][/url][red]([/red][blue]$line[/blue],[fuchsia]1[/fuchsia],[fuchsia]3[/fuchsia][red])[/red] eq [red]"[/red][purple]fac[/purple][red]"[/red][red])[/red] [red]{[/red] 
			[black][b]my[/b][/black] [blue]$facility[/blue] = [black][b]substr[/b][/black][red]([/red][blue]$line[/blue],[fuchsia]5[/fuchsia],[fuchsia]1[/fuchsia][red])[/red][red];[/red]
			[black][b]print[/b][/black] [red]"[/red][purple]Facility code               :  [blue]$facility[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
		[red]}[/red]
		
		[gray][i]### should be on line 8 of the file[/i][/gray]
		[olive][b]if[/b][/olive] [red]([/red][black][b]substr[/b][/black][red]([/red][blue]$line[/blue],[fuchsia]1[/fuchsia],[fuchsia]15[/fuchsia][red])[/red] eq [red]"[/red][purple]report_subtitle[/purple][red]"[/red][red])[/red] [red]{[/red]
			[black][b]print[/b][/black] [red]"[/red][purple]Original report subtitle line:  [blue]$line[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
			[black][b]my[/b][/black] [blue]$rs[/blue] = [black][b]substr[/b][/black][red]([/red][blue]$line[/blue],[fuchsia]17[/fuchsia][red])[/red][red];[/red]
			[blue]$line[/blue] = [red]"[/red][purple]%report_subtitle%[/purple][red]"[/red] . [blue]$facility[/blue] . [blue]$rs[/blue][red];[/red]
			[black][b]print[/b][/black] [red]"[/red][purple]Changed report subtitle line :  [blue]$line[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
		[red]}[/red]
	[red]}[/red]
	
	[url=http://perldoc.perl.org/functions/close.html][black][b]close[/b][/black][/url][red]([/red]INFILE[red])[/red][red];[/red]
[red]}[/red]
[black][b]close[/b][/black][red]([/red]DIR[red])[/red][red];[/red]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[/ul]
[/tt]

The biggest change is the addition of "use strict". That should always be there. The second biggest is the more meaningful error messages for open statements.

Obviously this code is untested, but it should at least give you ideas for the future.

- Miller
 
Miller:

Excuse me ... don't listen ... ARRRRGGGHHHHHHHHHHHHHHHHHHH!!!

OK - I feel better now.

Honestly, I played with quotes a couple of times and thought I finally had it correct. Goes to show us old dogs don't learn as easily as we think we can :)

I also appreciate the refactored version - I always enjoy seeing other approaches and learn something from each one of them ... this is no exception. Thank you - thank you - thank you ... !

Now ... it's time to stand in front of the mirror for the next 15 minutes and repeat over and over "WATCH THE QUOTES - WATCH THE QUOTES" ...

Best,

Tom

"My mind is like a steel whatchamacallit ...
 
Hi Tom,

I don't what programming environment that you use, but I would suggest that you pick up something that has good syntax highlighting. I use "TextPad", and all strings are highlighted in orange. This makes it easy to pick out things that should be strings and aren't or strings that do not have balanced quotes.

Anyway, it's just a suggestion. Hope you manage to get some rest now.

- Miller
 
I program primarily on an AIX v5 system and the only editor we have available is vi ... Offline, on my own machine, I use UltraEdit and it's set to highlight Perl syntax 'stuff' out of the box.

Wish we could get something more 'modern' on the AIX box but vi does work so I get by.

Again, thanks for the great information - really appreciate it!

Tom

"My mind is like a steel whatchamacallit ...
 
I am a bit surprised a professional perl programmer is not using "strict". Judging by the use of local(), which is doing nothing in this context, I am guessing your exposure to perl is from a while back:

Code:
local( @filenames ) = readdir( DIR );

Noting that Miller said his code was untested, there is an error:

Code:
        if (substr($line,1,3) eq "fac") {
            [b]my $facility[/b] = substr($line,5,1);
            print "Facility code               :  $facility\n";
        }
        
        ### should be on line 8 of the file
        if (substr($line,1,15) eq "report_subtitle") {
            print "Original report subtitle line:  $line\n";
            my $rs = substr($line,17);
            $line = "%report_subtitle%" . [b]$facility[/b] . $rs;
            print "Changed report subtitle line :  $line\n";
        }

$facility is out of scope when used in the second "if" block.


------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Miller's note about the error messages is a good one. I always include a $! somewhere in my die statements, so I can see why...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Kevin, I would normally use 'strict' since I know the value of using it. However, this was a (literally) overnight 'request' (translation: do this by 0800 tomorrow, no excuses) so I was simply pushing to get it working with plans on going back and making it 'pretty' (and more robust) once the initial management panic was over.

All: thanks for the comments, as always invaluable in my on-going learning experience.

Best,

Tom

"My mind is like a steel whatchamacallit ...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top