【问题标题】:Moving files to subdirectory in R based on file name根据文件名将文件移动到R中的子目录
【发布时间】:2021-07-12 10:49:00
【问题描述】:

所以我想根据文件名中的某个部分将文件复制到特定文件夹。为了您的概述,我将我的文件夹结构放在下面。在文件夹 D0 和 D1 中,我有多个文件(例如,我在这里放了两个文件的名称)以及文件夹 Weather 和 Temperature。我想将 .txt 文件移动到文件夹 Weather 或 Temperature,具体取决于文件名中是否包含 Weather 或 Temperature(请参阅我想要的)。

目前情况:

main Directory
|
|___ Experiment
        ├── D0
           ├── temperature
        │  └── Weather
           |__ Weather 100.txt
           |__ Temperature 100.txt
        └── D1
           ├── temperature
           └── weather
           |__ Weather 100.txt
           |__ Temperature 100.txt

我想要什么:

main Directory
    |
    |___ Experiment
            ├── D1
               ├── Weather
                        |__Weather 100.txt
               └── Temperature
                        |__ Temperature 100.txt

我尝试分步进行,因此首先使用 D0 移动天气,然后使用 D0 进一步移动温度文件,D1 天气,最后是 D1 温度文件。

然而,问题是双重的。第一个障碍是,虽然我得到了一个带有 Weather 的文件列表,但一旦我想将它复制到一个新目录,我就会收到一条错误消息,指出它无法复制该文件,因为没有这样的文件或目录。我的代码有什么问题?第二个问题是,如果我想这样做,代码效率就不那么高了,因为我必须运行代码四次(如果有两个以上的地图(D3、D4 等),则还要运行更多次。有没有一种使代码更高效的方法,以便一次完成所有工作?

【问题讨论】:

    标签: r move subdirectory movefile


    【解决方案1】:

    这是一个函数,它首先获取./Experiment 中的目录,然后将函数fun 应用于每个目录,将找到的文件移动到共享部分名称的子目录中。

    fun <- function(path){
      files <- list.files(path = path)
      files <- file.path(path, files)
      info <- file.info(files)
      dirs <- files[info$isdir]
      fls <- files[!info$isdir]
      out <- lapply(dirs, function(d){
        i <- grep(basename(d), fls, ignore.case = TRUE)
        if(length(i)){
          to <- file.path(d, basename(fls[i]))
          tryCatch(
            file.rename(fls[i], to = to),
            error = function(e) e
          )
        } else NULL
      })
      out
    }
    
    setwd('~/tmp/Experiment')
    d <- list.dirs(recursive = FALSE)
    sapply(d, fun)
    

    【讨论】:

    • 您好,感谢您的建议。这段代码正在完成部分工作。带有 FITC 的文件被移动到其对应的地图中。但是,名称中带有明场的文件不会移动到相应的文件夹中。作为输出,我得到 ./D0 ./D1 [1,] Null Null [2,] logical ,18 Logical, 40。这是他们的解决方案吗?
    • @alexdegrote1995 也许现在我已将ignore.case = TRUE 添加到grep
    【解决方案2】:

    以下函数检查文件名是否对应于目标目录(to),如果不对应:

    • 创建新的目标目录
    • 将文件移动到目录

    lapply 为每个目的地调用该函数:

    library(stringr)
    #Get all files
    path <- 'C:/temp/experiment'
    files <- list.files(path= path, recursive = TRUE)
    
    move.file <- function(filename,to = 'Brightfield') {
      fromdir <- dirname(filename)
      rootdir <- dirname(fromdir)
      filebase <- basename(filename)
      # File not in right directory
      if (str_detect(filebase, regex(to, ignore_case = TRUE))&
          !str_detect(fromdir, regex(to, ignore_case = TRUE))) {
        dir.create(file.path(rootdir,to),showWarnings = F)
        file.rename(from = file.path(path,filename),
                  to = file.path(path,rootdir,to,filebase))
      } else {F}
    }
    
    lapply(files, move.file, to='Brightfield')
    lapply(files, move.file, to='FITC')
    

    【讨论】:

    • 您好,感谢您的建议。如果我运行您的代码,我会在 lapply 函数处收到一个错误,指出找不到对象“B”。 B到底是什么?
    • 抱歉,这是一个测试子集。只需使用文件列表,请参阅我的编辑。
    • 嗨,我也试过这个代码,但是当我运行代码时,我得到一个错误,说“object” from is not found。为什么会出现这个错误?
    • @alexdegrote1995,感谢您的反馈,rootdir &lt;- dirname(fromdir) 中有错字,已更正
    猜你喜欢
    • 2014-06-06
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 2016-03-21
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多