I don't want to have to download anything additional to run my program (for the find rule).

I'm not sure that I understand your reluctance to install additional modules. One of the strengths of Perl is leveraging the modules available at CPAN. To install File::Find::Rule, you just need to type cpan -i File::Find::Rule. But if you're insisting on not installing additional modules, I won't pressure you to do what you don't want to do.

Instead, would you have an idea of how to improve my program with what I have right here and my current set of skills?

Unfortunately you really haven't provided enough details. I don't know what kind of files that you have that you're trying to copy/move and you're not really providing enough details about what copied and what didn't. Without more information, I'd have to agree with aaron_baugher's suggestions (Re: Perl - Copy files to a newly created folder) as a good starting point for debugging your script.

I really appreciate your help but I need something less complicated.

Other than possibly learning a new module, I really don't think that the code in my last post was really complicated. In fact, I personally think that trying to use opendir/readdir/closedir is actually a bit more complicated than using File::Find::Rule since you now have to do more work.

Here's a modification of my previous code using only core modules and using opendir/readdir/closedir in place of File::Find::Rule.

use strict; use warnings; use feature 'say'; use File::Copy; use File::Spec::Functions; use File::Path qw(make_path); use Cwd; # getting the "source" directory my $pwd = cwd(); my $source_dir = catdir($pwd,'source'); my @files; opendir(my $dir,$source_dir) or die "Unable to open directory '$source +_dir': $!"; # search for files in the specified directory while (my $item = readdir($dir)) { # skip . and .. next if ($item =~ m/^\./); # skip directories next if (-d $item); # if this is a file, add it to the @files array my $test = catfile($source_dir,$item); if (-f $test) {push @files,($item);} } closedir($dir); # process the files found foreach my $file (@files) { # get the file's extension my ($extension) = ($file =~ m/.+\.(.+)/); my $subdir = catdir($source_dir,$extension); # if the folder for the extension does not exist, create it if (!(-d $subdir)) {make_path($subdir);} my $source = catfile($source_dir,$file); my $target = catfile($subdir,$file); # copy the file to the appropriate folder copy($source,$subdir); # move the file to the appropriate folder #move($source,$target); }

In this version, I'm using a while loop to process through the contents of the directory. In that loop, I'm needing to be aware of and handle the special cases of . and .. plus and I need to ignore directories. Actually, I might have gotten away without checking for those items and using just the -f check. However, I put those additional checks in there, because I have gotten in trouble in the past for not checking them. So I now have a habit of including those checks whenever I use readdir to look at a directory's contents.

(I did notice that fishmonger showed a different method for finding files in a directory by using grep, but I thought I'd stick with using readdir since that's what you originally were trying to use.)

Also, notice that in the foreach loop that the @files array has only relative file names and not full path file names (i.e. has file.txt and not C:\directory\file.txt). Although I chose to "fix" this in the foreach loop, I could have done the "fix" back in the while loop before adding each file name to the @files array.

Let me share something else. I used to use the readdir method to go find items in a directory. But it can get real cumbersome - especially if you wish to search through subdirectories too. I kept seeing a lot of folks recommending File::Find as a better way to handle that kind of task. As I mentioned in my last post, I never could get my head wrapped around how to use File::Find. At some point I discovered File::Find::Rule and I found it to be super easy to understand how to use. Now when I need to go find and process directory contents, I just use File::Find::Rule. Doing so, I can accomplish the search with 10 or less lines instead of using one or more loops that feel complicated and hoping that I have code that handles everything properly. Although you may be more comfortable with using readdir for this current work, I'd recommend that you look into learning File::Find and/or File::Find::Rule at some point.


In reply to Re^3: Perl - Copy files to a newly created folder by dasgar
in thread Perl - Copy files to a newly created folder by Benichouniev

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.