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

Hello Monks,

I'm really not sure how to do this at all, I need to be able to compare the input from a user to files in a directory. Basically I have files in /Users/johnsmith/data, how do I take the user input from my script and determine if it matches the file name in that directory.

Example:

File name in the /Users/johnsmith/data drectory is 1234.tar.Z My Script So far:

#!/usr/bin/perl $fname = "empty"; while ($fname ne '/Users/johnsmith/data/$fname*'){ print "Please enter Filename: "; chomp($fname = <STDIN>); if ($fname ne '/Users/johnsmith/data/$fname*'){ print "File does not exist.\n\n"; print "Please enter Filename: "; } } print "I have found this $fname in your directory\n\n";
I know this is not correct and I can not figure out how to get this to work in Perl. Any help you could provide is greatly appreciated.

Replies are listed 'Best First'.
Re: How to compare User Input to a file Name
by Corion (Patriarch) on Sep 23, 2008 at 06:26 UTC

    The easiest way is to use the glob function to let Perl find the file for you:

    #!/usr/bin/perl -w use strict; # this is just so that glob() whitespace handling is sane use File::Glob qw(bsd_glob); my $fname = "empty"; my @found_files; while (! @found_files){ print "Please enter Filename: "; chomp($fname = <STDIN>); @found_files = glob( "/Users/johnsmith/data/$fname*" ); if (@found_files != 1) { if (@found_files == 0) { print "File '/Users/johnsmith/data/$fname*' does not ex +ist.\n\n"; } else { print "There are multiple files matching '/Users/johnsm +ith/data/$fname*':\n"; print "$_\n" for @found_files; }; }; } print "I have found this '$found_files[0]' in your directory\n\n";
      Thanks!

      I really appreciate the feed back.

Re: How to compare User Input to a file Name
by oko1 (Deacon) on Sep 23, 2008 at 16:24 UTC

    Rather than searching the list of files, you could just check if the file exists. This approach would eliminate a lot of testing and guessing.

    #!/usr/bin/perl -w use strict; my $path = '/Users/johnsmith/data'; my $fname; { print "Please enter a filename: "; chomp($fname = <STDIN>); last if -f "$path/$fname"; print "File does not exist!\n"; redo; } print "I have found '$fname' in '$path'.\n";

    Note: Just in case you aren't trying to play guessing games with the user, you might want to consider displaying the list of available filenames. Reading up on globbing with the '<*.c>' operator or the glob operator itself should prove useful for that.


    --
    "Language shapes the way we think, and determines what we can think about."
    -- B. L. Whorf
      Thanks for the advice.

      I am working on adding a file display portion to my script before I ask for the file name.

Re: How to compare User Input to a file Name
by rqatar2003 (Initiate) on Sep 23, 2008 at 16:52 UTC
    Hello Again Monks,

    As stated earlier I really appreciate the advice give so far. Now for the followup question. I am using this script to clean out directories.

    For this example I have 4 files in the /User/jsmith/data directory named test1-4. I want to delete all four of them so far I have the following:

    #!/usr/bin/perl -w use strict; use File::Glob qw(bsd_glob); use File::Path; my $fname = "empty"; my @found_files; my @found_files1; while (! @found_files) { print "Please enter the file name: "; chomp($fname = <STDIN>); @found_files = glob( "/Users/jsmith/data/$fname*" ); if (@found_files != 1) { print "File does not exist!"; }; }; print "The following files have been deleted: \n"; print "$_\n" for @found_files; while (@found_files != 0) { rmtree (@found_files); @found_files = glob( "/Users/jsmith/data/$fname*"); };
    Now my questions is: Is there a more effective way to use the rmtree to delete multiple directories other than using a while loop, like I did in my above code?
      Is there a more effective way to use the rmtree to delete multiple directories other than using a while loop
      I'm a little confused by your question. Are you trying to remove directories, or just some files within a directory? If you are just trying to remove individual files that match the specified input pattern, you probably could use rmtree from File::Path to remove your list of files. But I believe the most customary usage of rmtree is to remove directories. Here is a quote from the documentation:
      the rmtree function provides a convenient way to delete an entire directory subtree from the filesystem, much like the Unix command rm -r

      It is probably more appropriate in your case to use unlink. You could replace your while loop with:

      unlink @found_files;