Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Copy dir with space

by adriang (Sexton)
on Jul 10, 2014 at 08:38 UTC ( [id://1093008]=perlquestion: print w/replies, xml ) Need Help??

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

Hi All,

How can I copy/move dir with space. The Below code does not work.

opendir(my $dir, "/pr/perl_by_example") or die; opendir(my $dir2, "/pr/book") or die; while (my $file=readdir($dir)) { next if $file =~ /\./; copy("/pr/perl_by_example/$file", "/pr/book/") or die; }

Here are the dirs:

/pr/perl_by_example/Chapter 03 /pr/perl_by_example/Chapter 04 /pr/perl_by_example/Chapter 05 /pr/perl_by_example/Chapter 06 /pr/perl_by_example/Chapter 07 /pr/perl_by_example/Chapter 08 /pr/perl_by_example/Chapter 09 /pr/perl_by_example/Chapter 10 /pr/perl_by_example/Chapter 11 /pr/perl_by_example/Chapter 12 /pr/perl_by_example/Chapter 13 /pr/perl_by_example/Chapter 14 /pr/perl_by_example/Chapter 15 /pr/perl_by_example/Chapter 16 /pr/perl_by_example/Chapter 17 /pr/perl_by_example/Chapter 18 /pr/perl_by_example/Chapter 19 /pr/perl_by_example/Chapter 20

Thanks in advance

Replies are listed 'Best First'.
Re: Copy dir with space
by Discipulus (Canon) on Jul 10, 2014 at 08:48 UTC
    File::Spec is your friend. Path with spaces are shaggy beasts and very bad idea.

    Perlmonks have other similar questions and solutions like this one

    HtH
    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Copy dir with space
by Don Coyote (Hermit) on Jul 10, 2014 at 09:29 UTC

    Hi adriang,

    I contend there are several issues here, least of which is the filename containing a space.

    Firstly, use strict and warnings, if you did already, pls include with code example to show this. Secondly, copy, afaik is not a perl built-in (perldoc -f copy = not found).

    copy is a utility function which can be found in another module similar to File::Spec, I cannot recall which this moment. So basically, opendir to copy files from, readdir, filter, read contents into filehandle, open new filehandle name in destination directory, print contents.

    Untested! But, principally something like this, if the 'copy' containing module cannot be used.

    use strict; use warnings; use File::Spec::Functions qw/catfile/; my $dirnameto = catfile(qq{pr book}); my $dirnamefrom = catfile(qq{pr perl_by_example}); opendir( $dhandlefrom, $dirnamefrom )or die; while (my $file=readdir($dirhandlefrom)) { next if $file =~ /\./; my $filecontents; {local $/ = undef; # slurp mode; open( my $tfh, '<', catfile( qq{$dirnamefrom $file} ) ) or die; $filecontents = <$tfh>; close $tfh; # for clarity; } open( my $filecopy, '>', catfile( qq{$dirnameto $file} )) or die; + print { $filecopy } $filecontents; close $filecopy; }

    DC

      Thanks for the explain and for the answer. I'm afraid it does not work, I get: " Died at /proj/work.pl line 9. " Something is not working with "catfile"

        not quite. Couple of straight forward syntax errors. Catfile is probably fine, as the program died at an expected line, and, has compiled without complaining about the existence of the function catfile. But the arguments passed to it are amiss. This is probably due to the paths not being stated relatively in the rough draught.

        There was a thirdly, I did not mention previously. Thirdly, Paths and Files are different entities. You are using two directory opens when that is not needed for this copy operation. I think you may need to review the difference between a path and a file. To further complicate this issue, a Directory is a File. Well it is easier to say that both a directory and a file can be recognised as a string (or path). You then need to treat that string correctly depending whether it is a file, or a directory.

        P.S. That is what untested means, 'probably does not work, but you get the gist...'

        hope this helps. DoC

Re: Copy dir with space
by duelafn (Parson) on Jul 10, 2014 at 12:04 UTC

    Generally files with spaces are no problem as long as you are not using the shell. You didn't include your code for the copy function, but if it works on directories without spaces, I expect it uses the cp shell command (which can be dangerous depending on how it is used and exactly how it is implemented).

    The code below will be safe as it never passes the file names to the shell.

    #!/usr/bin/perl use strict; use warnings; use Path::Class; use File::Copy::Recursive qw/ dircopy /; my $source = "/pr/perl_by_example"; my $dest = "/pr/book"; for my $path (dir($source)->children) { next if $path =~ /\./; my $target = dir($dest, $path->basename); dircopy $path, $target or die "Error copying $path: $!"; }

    dir($source)->children will not include the '.' and '..' special directories, but will include everything else (including hidden files and directories). Thus, I left your $path =~ /\./ test in place. However, that test looks suspicious since it will match a '.' anywhere in the name (beginning, middle, end) so will usually match file names as well (but not always, since not all file names have an extension). To exclude hidden files and directories use: next if $path =~ /^\./; To exclude all files and only copy directories next unless $path->is_dir; If you want to exclude both (all hidden files and directories as well as all file), I would suggest including both tests separately:

    for my $path (dir($source)->children) { next if $path =~ /^\./; # exclude hidden files and directories next unless $path->is_dir; # exclude files my $target = dir($dest, $path->basename); dircopy $path, $target or die "Error copying $path: $!"; }

    Good Day,
        Dean

      Thanks very much, it did the work :-) Adrian

Re: Copy dir with space (Path::Tiny)
by Anonymous Monk on Jul 10, 2014 at 09:19 UTC

    The Below code does not work.

    Yes, it doesn't compile for me either :) This does compile

    #!/usr/bin/perl -- use strict; use warnings; use Path::Tiny qw/ path cwd /; my @files = grep { -f $_ } path( '/pr/perl_by_example/' )->children(); for my $source ( @files ) { my $destination = path( "/pr/book/", $source->basename ); $source->copy( $destination ); }

      A very nice code snippet. Thank you, Anonymous Monk.

      Thanks for the quick replay, Unfortunately the dest dir is empty and I don't get any error when I run the script.

        well, then you got no files

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1093008]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2024-04-24 18:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found