Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks Yet another retarded newbie comes your way. I am writing a basic script to write to open, read, and write to the same file, all textbook stuff but I cannot get it to work:
#!/usr/bin/perl -w opendir(TEST, "test") or die "Can't open dir\n"; @testfiles = readdir (TEST); closedir(TEST); foreach $testfiles(@testfiles){ open(FILE, "test/$testfiles") or die "can't open file"; while ($line = <FILE>){ if ($line =~ /mods=[0-9][0-9]/){ $line =~ s/mods=[0-9][0-9]//; printf FILE $line; }; } }
Error message says "Can't open file". Any help. Thanks.

Replies are listed 'Best First'.
Re: BAsic File I/O
by blakem (Monsignor) on Aug 21, 2001 at 01:45 UTC
    Whenever this happens, the first step is to make your error message more informative. Try:

    open(FILE,"test/$testfiles") or die "can't open file 'test/$testfiles' +: $!";
    The $! will tell you what the OS thinks is the problem, and having the filename in the error message will help track down the problem as well.

    -Blake

Re: BAsic File I/O
by dga (Hermit) on Aug 21, 2001 at 01:50 UTC

    A couple of things. 1. Your list of stuff in the test directory will have some directory entries in it, at least . and .., which open will not open.
    2. If you do open a file for output and read line at a time it will wipe out the original file so you will need to read in the files then open for output then write.

    Look at the -i flag to perl which may give some direction. If you want to use readdir you will need to stat the files to see if they are regular files and only open those, read in the data, reopen the file for output and write. If you have a failure (as in power) you will lose your original file.

    I would recommend a two tier approach. Open a temp file to write and open the file to read, copy changes into the temp file and then use the rename() function to change the name back to the current filename which will be a lot safer to your original data.

Re: BAsic File I/O
by tachyon (Chancellor) on Aug 21, 2001 at 06:28 UTC

    Aside from adding $! to get the systems error message in your die you have a number of other errors.

    You don't seem to want printf. print FILE $line will just print out the line to the filehandle FILE. printf in Perl means print formatted and needs the format specified. See perlman:perlfunc for details. Write a bit of C by any chance :-)

    Even with print this will still not modify you files as you obviously want to do. This is beacuse you open the file without an input operator. These include < for open for reading > for open for writing and >> for open for appending. See perlman:perlop for more details.

    To find the solution you want do a Super Search for "in place edit" in the text and "chipmunk" for the author. You will find Re: modifying a text file on Win32 which does part of what you want. Have a look at the whole thread

    Update

    This is so common that a snippet seemed in order. This is at Inplace Editing

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: BAsic File I/O
by Cine (Friar) on Aug 21, 2001 at 15:09 UTC
    This is done much easiere with:
    find test/ -type f -print0 | xargs -0 perl -i -pe 's/mods=\d\d//g'


    T I M T O W T D I