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

#!/usr/bin/perl -w use File::Find; find(\&dir_explorer, "/home/gw/A/S/d"); sub dir_explorer { my $entry = $_; if (-d $entry) { $dir=$entry; open(FILE, "> $dir") or die "Can not open $dir with permission +for writing: $!\n"; close(FILE); }; if (-f $entry) { open(FILE, ">> $dir") or die "Can not open $dir: $!\n"; print FILE "$file\n"; close(FILE); }; };
Hi, at first i am a beginner. So i am so sorry,if my questions seem to be stupid. I have some questions: - 1.if-command: open(FILE, "> $dir") doesn`t create a text-file with the name of the visited directory. How can I solve this problem. - 2.if-command: I want to write the files, which are in the directory in the text-file (which carries the name of the directory). thanks for your help

Replies are listed 'Best First'.
Re: Some problems with my code - Help...
by SuperCruncher (Pilgrim) on May 26, 2003 at 20:43 UTC
    First of all, don't worry about asking questions that you think are stupid.

    Your code has a number of problems:

    • The first open call will, AFAIK, always fail because you are chdir()ed to the directory that contains the directory you've just found. So you're trying to write to a file with the same name as a directory. See the section about "the wanted() function" in the File::Find manpage.
    • I don't thint the space in "> $dir" is a good idea - do ">$dir" instead.
    • What is $file? You only use it once as far as I can see. This is where use warnings; can help you.

    Anyway, none of this really helps you solve your problem. I would put the directory listings in a separate directory. Take a look at this code (untested):

    use strict; use warnings; use File::Find; my $listings_dir = 'c:/listings'; find(\&callback, 'c:/tmp'); sub callback { my $file = $_; # Check to see if $file is a directory if (-d $file) { # Get a list of all the files in the directory (inefficient) # (If you only want the filenames rather than paths as well, # investigate using File::Basename. If you want just the files # in a directory, and directories within the directory, # consider putting grep { -f $_ } before the glob. my (@files) = glob($File::Find::dir . "/$_/*"); # Save this list to a file open LISTING, ">$listings_dir/list$_.txt"; print LISTING join ("\n", @files); close LISTING; } }
    Good luck with learning Perl. I strongly recommend learning Perl properly--get yourself a copy of "Learning Perl". Your investment in learning Perl will pay back very quickly.

      There is nothing wrong with open(FH, "> $file");

      perldoc -f open says:

      The filename passed to 2-argument (or 1-argument) form of open() will have leading and trailing whitespace deleted
      I prefer to put some whitespace between the permissions operator and the filename, others do not. It's a style thing, but there is nothing wrong with it.

      Preferably use warnings instead of perl -w. There is a thread here explaining why, but I can't track it down right now. See perldoc perllexwarn for more info.
      You should consider using the strict pragma as well as the warnings pragma.

      Another minor point - I personally find

      my $dir = $entry; open(FILE, "> $dir") or die "Can't open file, $dir: $!";
      slightly grating.
      It's a file you want to create - I initially couldn't figure out if you really wanted opendir to open a directory handle, or if you wanted:
      my $file = $entry; open(FILE, "> $file") or die "Can't open file, $file: $!";
      It's little things like that which make maintenance programmers go insane :-)

      As another poster has already pointed out, you can't go creating files, directories, pipes etc, in the same directory with the same name as an existing file/dir/pipe.


      If the information in this post is inaccurate, or just plain wrong, don't just downvote - please post explaining what's wrong.
      That way everyone learns.

      Sorry, $file is wrong.- correct:$entry. thank you for your help. to the other people: thank you, too.
Re: Some problems with my code - Help...
by tos (Deacon) on May 26, 2003 at 21:28 UTC
    Hi,

    Question 1: You cannot write to a file with the name of an existing directory. Possibly helpful could be an extention ".txt" to that file

    $dir=$entry . ".txt";
    Question 2: File::Find's subroutine is called for any single item while traversing the directory-tree. If you change the $file in the second if-block to $entry your code will run proper. But i think the result of scattered $dir.".txt"-files in the whole tree which are often empty will be not what you wanted.

    A good explanation how File::Find works could be found in spurperl's Beginners guide to File::Find