不跟随符号链接复制文件
Copying files without following symbolic links
像这样在 R 中递归复制文件时:
file.copy(from = "/path/to/sdir", to = "/path/to/dest", recursive=TRUE)
符号链接的目标被复制。我想让 R 按原样复制任何符号而不是它的目标。如果那不可能,我想跳过复制它。
试试 Sys.readlink
(感谢@antonio)、file.info
(对于 $isdir
)和一些相关函数的组合。
copy_dir <- function(src, dest, ..., recursive = TRUE, overwrite = FALSE, mode = "0700") {
work <- data.frame(
src = list.files(src, recursive = recursive, full.names = TRUE, include.dirs = TRUE)
)
work$link <- Sys.readlink(work$src)
work$isdir <- file.info(work$src)$isdir
# if something is both a link and a dir, then remove all children
srcdirlinks <- work$src[work$isdir & nzchar(work$link)]
work <- work[rowSums(sapply(srcdirlinks, startsWith, x = work$src)) < 1 |
work$src %in% srcdirlinks,]
work$dest <- gsub(paste0("^", src), dest, work$src)
if (!overwrite) {
probs <- file.exists(work$dest)
if (any(probs)) {
stop("dest files exist, set overwrite=TRUE to force: ",
paste(sQuote(work$dest[probs]), collapse = ","))
}
}
Vectorize(dir.create)(work$dest[work$isdir & !nzchar(work$link)],
recursive = TRUE, mode = mode, showWarnings = FALSE)
isfile <- !nzchar(work$link) & !work$isdir
file.copy(work$src[isfile], work$dest[isfile])
islink <- nzchar(work$link)
file.symlink(work$link[islink], work$dest[islink])
}
功能证明:
system("find somedir -ls")
# 40135 4 drwxr-xr-x 4 r2 r2 4096 Jul 17 10:14 somedir
# 124826 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/file2
# 124836 0 lrwxrwxrwx 1 r2 r2 5 Jul 17 08:24 somedir/file3s -> file1
# 124825 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/file1
# 124822 0 lrwxrwxrwx 1 r2 r2 4 Jul 17 08:06 somedir/dir3s -> dir1
# 124789 4 drwxr-xr-x 2 r2 r2 4096 Jul 17 08:24 somedir/dir2
# 124824 0 lrwxrwxrwx 1 r2 r2 7 Jul 17 08:24 somedir/dir2/dir21s -> ../dir1
# 124832 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/dir2/file22
# 124833 0 lrwxrwxrwx 1 r2 r2 14 Jul 17 08:23 somedir/dir2/file21s -> ../dir1/file11
# 40136 4 drwxr-xr-x 2 r2 r2 4096 Jul 17 08:23 somedir/dir1
# 124828 0 lrwxrwxrwx 1 r2 r2 6 Jul 17 08:07 somedir/dir1/file12s -> file11
# 124827 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/dir1/file11
copy_dir("somedir", "somedir2", recursive = FALSE)
# [1] TRUE TRUE
system("find somedir2 -ls")
# 124837 4 drwx------ 4 r2 r2 4096 Jul 17 10:38 somedir2
# 124841 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file2
# 124843 0 lrwxrwxrwx 1 r2 r2 5 Jul 17 10:38 somedir2/file3s -> file1
# 124840 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file1
# 124842 0 lrwxrwxrwx 1 r2 r2 4 Jul 17 10:38 somedir2/dir3s -> dir1
# 124839 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir2
# 124838 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir1
unlink("somedir2", recursive = TRUE)
copy_dir("somedir", "somedir2", recursive = TRUE)
# [1] TRUE TRUE TRUE TRUE TRUE
system("find somedir2 -ls")
# 124837 4 drwx------ 4 r2 r2 4096 Jul 17 10:38 somedir2
# 124843 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file2
# 124851 0 lrwxrwxrwx 1 r2 r2 5 Jul 17 10:38 somedir2/file3s -> file1
# 124842 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file1
# 124850 0 lrwxrwxrwx 1 r2 r2 4 Jul 17 10:38 somedir2/dir3s -> dir1
# 124839 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir2
# 124848 0 lrwxrwxrwx 1 r2 r2 7 Jul 17 10:38 somedir2/dir2/dir21s -> ../dir1
# 124841 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/dir2/file22
# 124849 0 lrwxrwxrwx 1 r2 r2 14 Jul 17 10:38 somedir2/dir2/file21s -> ../dir1/file11
# 124838 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir1
# 124844 0 lrwxrwxrwx 1 r2 r2 6 Jul 17 10:38 somedir2/dir1/file12s -> file11
# 124840 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/dir1/file11
像这样在 R 中递归复制文件时:
file.copy(from = "/path/to/sdir", to = "/path/to/dest", recursive=TRUE)
符号链接的目标被复制。我想让 R 按原样复制任何符号而不是它的目标。如果那不可能,我想跳过复制它。
试试 Sys.readlink
(感谢@antonio)、file.info
(对于 $isdir
)和一些相关函数的组合。
copy_dir <- function(src, dest, ..., recursive = TRUE, overwrite = FALSE, mode = "0700") {
work <- data.frame(
src = list.files(src, recursive = recursive, full.names = TRUE, include.dirs = TRUE)
)
work$link <- Sys.readlink(work$src)
work$isdir <- file.info(work$src)$isdir
# if something is both a link and a dir, then remove all children
srcdirlinks <- work$src[work$isdir & nzchar(work$link)]
work <- work[rowSums(sapply(srcdirlinks, startsWith, x = work$src)) < 1 |
work$src %in% srcdirlinks,]
work$dest <- gsub(paste0("^", src), dest, work$src)
if (!overwrite) {
probs <- file.exists(work$dest)
if (any(probs)) {
stop("dest files exist, set overwrite=TRUE to force: ",
paste(sQuote(work$dest[probs]), collapse = ","))
}
}
Vectorize(dir.create)(work$dest[work$isdir & !nzchar(work$link)],
recursive = TRUE, mode = mode, showWarnings = FALSE)
isfile <- !nzchar(work$link) & !work$isdir
file.copy(work$src[isfile], work$dest[isfile])
islink <- nzchar(work$link)
file.symlink(work$link[islink], work$dest[islink])
}
功能证明:
system("find somedir -ls")
# 40135 4 drwxr-xr-x 4 r2 r2 4096 Jul 17 10:14 somedir
# 124826 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/file2
# 124836 0 lrwxrwxrwx 1 r2 r2 5 Jul 17 08:24 somedir/file3s -> file1
# 124825 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/file1
# 124822 0 lrwxrwxrwx 1 r2 r2 4 Jul 17 08:06 somedir/dir3s -> dir1
# 124789 4 drwxr-xr-x 2 r2 r2 4096 Jul 17 08:24 somedir/dir2
# 124824 0 lrwxrwxrwx 1 r2 r2 7 Jul 17 08:24 somedir/dir2/dir21s -> ../dir1
# 124832 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/dir2/file22
# 124833 0 lrwxrwxrwx 1 r2 r2 14 Jul 17 08:23 somedir/dir2/file21s -> ../dir1/file11
# 40136 4 drwxr-xr-x 2 r2 r2 4096 Jul 17 08:23 somedir/dir1
# 124828 0 lrwxrwxrwx 1 r2 r2 6 Jul 17 08:07 somedir/dir1/file12s -> file11
# 124827 0 -rw-r--r-- 1 r2 r2 0 Jul 17 08:07 somedir/dir1/file11
copy_dir("somedir", "somedir2", recursive = FALSE)
# [1] TRUE TRUE
system("find somedir2 -ls")
# 124837 4 drwx------ 4 r2 r2 4096 Jul 17 10:38 somedir2
# 124841 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file2
# 124843 0 lrwxrwxrwx 1 r2 r2 5 Jul 17 10:38 somedir2/file3s -> file1
# 124840 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file1
# 124842 0 lrwxrwxrwx 1 r2 r2 4 Jul 17 10:38 somedir2/dir3s -> dir1
# 124839 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir2
# 124838 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir1
unlink("somedir2", recursive = TRUE)
copy_dir("somedir", "somedir2", recursive = TRUE)
# [1] TRUE TRUE TRUE TRUE TRUE
system("find somedir2 -ls")
# 124837 4 drwx------ 4 r2 r2 4096 Jul 17 10:38 somedir2
# 124843 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file2
# 124851 0 lrwxrwxrwx 1 r2 r2 5 Jul 17 10:38 somedir2/file3s -> file1
# 124842 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/file1
# 124850 0 lrwxrwxrwx 1 r2 r2 4 Jul 17 10:38 somedir2/dir3s -> dir1
# 124839 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir2
# 124848 0 lrwxrwxrwx 1 r2 r2 7 Jul 17 10:38 somedir2/dir2/dir21s -> ../dir1
# 124841 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/dir2/file22
# 124849 0 lrwxrwxrwx 1 r2 r2 14 Jul 17 10:38 somedir2/dir2/file21s -> ../dir1/file11
# 124838 4 drwx------ 2 r2 r2 4096 Jul 17 10:38 somedir2/dir1
# 124844 0 lrwxrwxrwx 1 r2 r2 6 Jul 17 10:38 somedir2/dir1/file12s -> file11
# 124840 0 -rw-r--r-- 1 r2 r2 0 Jul 17 10:38 somedir2/dir1/file11