I am using Linux and I have a directory structure as follows:
- RootFolder
* DirectoryA
* * Directory(X) [1]
* * Directory Y
* * DirectoryZ
* DirectoryB
Note the special characters such as brackets, square brackets and spaces.
In practice, DirectoryA has a lot more subdirectories, but for the purpose of this example, let's say that I want to copy the 2 most recently created directories (with contents) from DirectoryA to DirectoryB.
My first attempt at this was to cd to RootFolder and run the following command:
ls -lt DirectoryA | head -2 | awk '{print "cp -r " $9 " DirectoryB/"$9 | sh
This failed because of special characters in various subdirectories and returned:
cp: can't stat Directory
cp: can't stat Directory(X)
Can someone advise on how to modify my command to work with spaces and special characters?
Quoting helps:
ls -t DirectoryA | head -2 | awk '{print "cp -vr \"DirectoryA/" $0 "\" DirectoryB/" }' |sh
I added a -v
option to show what it does:
`DirectoryA/DirectoryZ' -> `DirectoryB/DirectoryZ'
`DirectoryA/Directory Y' -> `DirectoryB/Directory Y'
However, you would run into problems if the filenames contain double quotes or if they contain characters which ls
does not represent except as question-marks.
As alternative, you can do the whole job using perl , with the help of built-in module File::Spec::Functions
, that handles files and their paths, and external File::Copy::Recursive
, that you will need to install from CPAN
or similar, and copies directories recursively:
perl -MFile::Spec::Functions=catfile,catdir,splitdir -MFile::Copy::Recursive=rcopy -E '
$dest = catdir(($ARGV[0], $ARGV[2]));
$orig = catdir(($ARGV[0], $ARGV[1]));
opendir $dh, $orig or die;
for $f (
sort { (stat $b)[9] <=> (stat $a)[9] }
grep { -d $_ and $_ !~ m/\.\.?$/ }
map { catfile $orig, $_ }
readdir $dh)[0..1] ) {
rcopy($f, catdir $dest, (splitdir $f)[-1]) or die $!;
}
' /your/path/to/RootFolder DirectoryA DirectoryB
It accepts three arguments, the first one is the path to your RootFolder
, the second one the from
, and the last one the to
. The grep
filters out non-directory files and special entries, and the sort
checks its modification time, the slice [0..1]
only gets the two most recent based in the modification time.
It worked in my test but if it does not match exactly for you, I hope it is near the finish line so you can give it a boost to it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.