2015-05-06 38 views
2

我有一個R函數,它使用帶有相對符號鏈接的目錄(例如../../data)作爲模板。我知道相關鏈接將是有效的,因爲函數將模板放入已知文件結構的特定部分。 file.copy函數可以使用recrusive = TRUE複製目錄,但它會將符號鏈接轉換爲它們指向的目錄的副本。 Linux系統命令cp -r path1 path2將正確複製鏈接,但我希望儘可能使用R函數。如何使用R中的符號鏈接複製文件夾/目錄?

如何複製R中包含指向目錄之外的相對符號鏈接的目錄?

我知道我可以寫我自己的函數,recursivly列表文件(list.dirs),發現符號鏈接(Sys.readlink),並重新創建它們(file.link),而複製所有其他文件,但我想知道,如果這個功能已經存在。

回答

3

我想出了一個解決方案,所以我想我會張貼它,以防其他人可能需要這樣做,實際上沒有一個更傳統的方式來做到這一點。我仍然有興趣聽到其他答案!

我想出了以下功能:

#=================================================================================================== 
#' Copy folders with links 
#' 
#' Copies folders like \link{\code{file.copy}} except it replicates links correctly on unix-like 
#' systems. 
#' 
#' @param from (\code{character}) The path to the folder to be copied 
#' @param to (\code{character}) Where to copy the folder to. 
#' 
copy_folder_with_links <- function(from, to) { 
    target <- file.path(to, basename(from)) 
    if (file.exists(target)) stop(paste0("Target folder ", target, " already exists.")) 
    # Get list of all files/folders to copy ---------------------------------------------------------- 
    path <- data.frame(target = list.files(from, recursive = TRUE, all.files = TRUE, include.dirs = TRUE)) 
    path$from <- file.path(from, path$target) 
    path$to <- file.path(to, basename(from), path$target) 
    # Get type of file/folders ----------------------------------------------------------------------- 
    path$type <- factor("file", levels = c("file", "folder", "link")) 
    path$type[file.info(path$from)$isdir] <- "folder" 
    path$type[Sys.readlink(path$from) != ""] <- "link" 
    # Remove all files that are descendants of links ------------------------------------------------- 
    is_child <- function(query, refs) { 
    sapply(refs, function(x) grepl(paste0("^", x), query) & query != x) 
    } 
    path <- path[!sapply(path$from, function(x) any(is_child(x, path$from) & path$type == "link")), ] 
    # Make copy -------------------------------------------------------------------------------------- 
    invisible(lapply(path$to[path$type == "folder"], dir.create, recursive = TRUE)) 
    invisible(file.copy(from = path$from[path$type == "file"], to = path$to[path$type == "file"])) 
    invisible(file.symlink(Sys.readlink(path$from[path$type == "link"]), path$to[path$type == "link"])) 
} 

它就像file.copy(以較少的選項),但正確地複製鏈接。它的工作原理

  1. 讓所有的文件/文件夾使用list.files(from, recursive = TRUE, all.files = TRUE, include.dirs = TRUE)
  2. 確定它們是否是一個文件,文件夾或鏈接
  3. 從列表中刪除鏈接的文件夾的後代被複制的列表(因爲鏈接後跟list.files
  4. 複製文件夾,文件和鏈接(按此順序)
相關問題