Moving multiple specific folders on windows

Question:

I have a list of multiple specific directories that I would like to move to another folder on Windows.
The list is stored in a txt.file which contains the paths of these directories:

"C:/Path/to/my/folder1/"
"C:/Path/to/my/folder4/"
"C:/Path/to/my/folder9/"

I would like to move all these folders including there subfolders to a new directory:

C:/Path/to/new/directory/

Is there a smart way to do this by powershell, python or R on windows?

Edit (Sorry, didn’t include my first attempts initially):

I had previously tried using the "file.copy(list_of_paths, target_path)" command in R, but it always returned "FALSE FALSE". If I understood correctly, it seems that R on windows has difficulties handling folders rather than files (I’m used to unix and haven’t come across that issue before).

The other thing I tried was using the Copy-Item command on Powershell (Get-ChildItem -Path 'C:Pathoffiles' -Recurse| Copy-Item -Destination 'C:Pathtotarget'), but I’m not sure how to load a list of paths in Powershell.

Thanks so much!

Asked By: yakumo

||

Answers:

Here is a solution using R. Assuming that your filepaths are stored in a list fpath:

file.copy(fpath, "C:/Path/to/new/directory/")
Answered By: tacoman

Alternate Solution(s)

The previous answer provides a solution in R for copying recursively the folders from source to target.

Per your question, you need to move the folders and maintain their relative sub-folder structure from the root path.


I know that’s not a big deal because you can simply copy recursively over the folders and delete originals, however, in general moving is much faster than copying and it’s what you asked for so here’s what I’ve got.


I propose the following solutions:

PowerShell Solution

The simplest solution is to simply run:

# showing different ways of specifying paths
$fromDirs = @( 
    ".folder1"
    "C:Pathtomyfolder2"
    "$env:USERPROFILEDocumentsTestDir"
)

$destDir = "$HOMEDesktop"

ForEach ($dir in $fromDirs) {
    Move-Item -Path $dir -Destination $destDir -Force
}

Another, more involved PowerShell solution is as follows:

$fromDirs = @(
    "C:Pathtomyfolder1"
    "C:Pathtomyfolder2"
    "C:Pathtomyfolder3"
)

$toDir = "C:Pathtomydestination"

$fromDirs | ForEach-Object {
    $fromDir = $_
    $Files = Get-ChildItem -Path $fromDir -Recurse -File
    $Files | ForEach-Object {
        $File = $_
        $RelativePath = $File.FullName.Replace($fromDir, '')
        $Destination = Join-Path -Path $toDir -ChildPath $RelativePath
        $DestinationDir = Split-Path -Path $Destination -Parent
        if (-not (Test-Path -Path $DestinationDir)) {
            New-Item -Path $DestinationDir -ItemType Directory -Force
        }
        Move-Item -Path $File.FullName -Destination $Destination -Force
    }
}

this more advanced solution deals with the relativistic hierarchy issues when moving recursive paths.

Relative Folder Hierarchy

In order to maintain relative path consistency (i.e. when moving the folders and subfolders, you will need to create the relative path structure first before moving/copying the files over), a little more advanced solution is necessary than simply running Move-Item -Path $fromDir -Destination $toDir -Force since the Move-Item cmdlet does not support recursion (and it shouldn’t for various reasons).

R Solution

In R, I would go with fs::dir_copy() over base R (a practice I usually avoid) due to its file system management practices in Windows and its dir_copy() function being more robust than base R file.copy() in this scenario.

require(fs)
fs::dir_copy(c("folder1", "folder2"), "DestinationFolder")

But to address the topic of moving instead of copying the best solution in R is to use base R’s file.rename() function.

# this moves a directory from one location to another:
file.rename(folder_old_path, path_new)

for multiple directories with subdirectories:

to <- "todir"
froms <- c("dir1", "dir2")
tos <- paste0(to, "/", froms)

file.rename(froms, tos)

will result in "dir1" and "dir2" moving to "todir/dir1/" and "todir/dir2/".

Note that if "todir" doesn’t exist you will need to check that first via if (dir.exists(to)) { ... }


Copying vs. Moving

Just like on UNIX, copying is used to copy from one place to another while moving is used to move a file or folder. Moving will not have a flag for recursion (i.e. no -r flag) because it will automatically move all sub-folders and files to the specified destination’s path. Copying, however, allows you to specify the recursion option to copy directories recursively. Lastly, be wary of overwriting pre-existing files in the destination path.

Also, if you are on Windows you should use the correct path separators ( instead of /; or to be safe just go with double \).

Answered By: jimbrig
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.