递归复制文件夹在R中

26

我在这些函数中是否漏掉了什么?
我想要从一个位置复制一个带有文件和子文件夹的文件夹到另一个位置。我试着使用 file.copy(from, to, recursive=TRUE),但是它会显示以下错误信息:

In file.copy("my_folder", "new_folder", :
'recursive' 将被忽略,因为 'to' 不是单个现有目录

结果是一个名为 new_folder 的空文件。

是否有一种方法可以在 R 中复制完整的文件夹结构?


我传递文件夹名称。这些文件夹中有子文件夹和文件... 我想在一个新目录中创建完整的子文件夹结构... 我知道函数名并不真正意味着“复制文件夹”,但由于有递归标志,我认为它可能有所帮助,并且在R中没有文件夹或目录复制函数。 - drmariod
可以举个例子吗?我尝试重新创建您的问题,但我不知道是否有正确的文件夹结构。到目前为止,我创建了: content/ content/test.txt content/test1.txt content/sub/ content/sub/sub_test.txt 这似乎是您在第二句话中解释的内容,但我不明白为什么您需要通过多个目录 :) - Verena Haunschmid
你需要更正结构,我想要将content复制到content2中。所以基本上是创建一个与content相同结构的新文件夹。我只想递归地复制到一个新目录中。 - drmariod
啊,现在醍醐灌顶了... :-) “递归”将被忽略,因为“to”不是单个现有目录... 当我首先创建“content2”,然后使用“file.copy('content','content2',recursive = TRUE)”时,它按预期工作... 我只是想用file.copy函数来创建目录。 - drmariod
1
终于! :) 这就是我困惑的地方 ;) - Verena Haunschmid
显示剩余3条评论
6个回答

29

好的,我刚刚弄清楚了错误的意思... :-) 我需要提前创建新目录,现在我可以复制所有内容了...

dir.create('new_folder')
file.copy("my_folder", "new_folder", recursive=TRUE)

这按预期运作。


8
但是看起来你会得到new_folder/new_folder/files,是吗? - Matifou
1
@Matifou 如果你想要避免这种情况的话,请检查我的答案。 - emilBeBri

19

我认为 R.utils::copyDirectory(oldDir, newDir) 是你所问的问题的解决方案。它也不需要先创建 newDir


14

正如评论中@matifou所说,问题提问者本人所接受的答案有点令人困惑,因为你最终会得到一个名称与复制文件夹相同的文件夹内部的复制文件夹... 为了避免这种情况,请改为执行以下步骤:

场景:您想将文件夹X移动到文件夹Z中。

# create empty folder Z inside folder X
dir.create('(...)/folder_X/folder_Z')
# copy the folder
file.copy('(...)/path_to_folder_Z', '(...)/folder_X')

因此,file.copy的第二个参数应该只是文件夹folder_X,而不是文件夹folder_X内新创建的文件夹folder_Z。

因为如果这样做,文件夹结构将会像这样,这可能不是你想要的:

(...)/folder_X/folder_Z/folder_Z

(也许这可以帮助某些人节省我花费约10分钟才能理解的时间)


3
我认为如果folder_X和folder_Z有相同的父目录,这种方法可能行不通。(例如,如果用户想将<my_path>/folder_X复制到<my_path>/folder_X_copy怎么办?) - GerasimosPanagiotakopoulos

11
如果您想将一个文件夹中的文件复制到另一个文件夹中,例如:
dir1/file1.txt
dir1/nested/file2.txt

致:

dir2/file1.txt
dir2/nested/file2.txt

那么这段代码是可行的:

from <- "dir1"
to   <- "dir2"
file.copy(list.files(from, full.names = TRUE), 
          to, 
          recursive = TRUE)

不要在list.files()命令中使用recursive=TRUE,否则会失去嵌套。
file.copy(list.files(from, full.names = TRUE, recursive = TRUE), 
          to, 
          recursive = TRUE)

# incorrect
# dir2/file1.txt
# dir2/file2.txt

以上其他答案未能解决以下情况,例如:

file.copy(from, to, recursive=TRUE)

# incorrect - makes:
# dir2/dir1/file1.txt
# dir2/dir1/nested/file2.txt

file.copy('(...)/path_to_folder_Z', '(...)/folder_X')
# overwrites existing folder if in same parent directory

那是最好的答案,谢谢。 - Laurent Bergé

2

我更愿意编写一个R函数,使用终端复制目录。这是我使用的代码,但请注意,我目前仅为Linux和OSX编写了它。

dir.copy <- function(from, to) {
  os <- Sys.info()['sysname']
  if (os == "Darwin" || os == "Linux") {
    command <- sprintf("cp -R '%s' '%s'", from, to)
    system(command, intern = TRUE)   
  }
}

快速、简单且运行得非常好。

谢谢,我以前也这样做过,如果需要加速的话... 但是我会先进行一些清理。检查位置是否存在,没有;,还有其他的可能... 我猜你不希望用户像 from <- ". /dev/null ; rm -rf /" 这样命名文件夹... - drmariod

-1

这里有另一种可能性:

create_Directory <- function(source_Directory = "C:/dir1",
                             target_Directory = "C:/dir2")
{
  setwd(source_Directory)
  list_Dirs <- list.dirs()
  setwd(target_Directory)
  bool_Dir_Exists <- dir.exists(list_Dirs)
  dirs_To_Create <- list_Dirs[!bool_Dir_Exists]
  for(dir in dirs_To_Create)
  {
    dir.create(dir)
  }
}

copy_Content_From_One_Directory_To_Another <- function(source_Directory = "C:/dir1",
                                                       target_Directory = "C:/dir2")
{
  #### Create the sub directories ####
  create_Directory(source_Directory = source_Directory,
                   target_Directory = target_Directory)

  #### Copy the files ####
  setwd(source_Directory)
  list_Files <- list.files(recursive = TRUE, full.names = TRUE)
  list_Files <- gsub(pattern = paste0("(\\.)",.Platform$file.sep), replacement = "", list_Files)

  file.copy(from = paste0(source_Directory,  .Platform$file.sep 
, list_Files),
            to = paste0(target_Directory, .Platform$file.sep , list_Files))
}

copy_Content_From_One_Directory_To_Another()



这段代码不是跨平台兼容的,因为它依赖于正斜杠作为路径分隔符。尝试使用.Platform$file.sep代替。 - Brandmaier
我修改了代码,包括.Platform$file.sep。这是否回答了您的疑虑? - Emmanuel Hamel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接