【问题标题】:R move files with specific name pattern to folder in different subdirectoriesR将具有特定名称模式的文件移动到不同子目录中的文件夹
【发布时间】:2021-06-24 19:30:14
【问题描述】:

我想根据文件名称中的某个部分将文件复制到特定文件夹。您将在下面找到我的文件夹结构以及文件所在的位置。在 D0 和 D1 文件夹中,您会找到类似以下结构命名的文件:20210308_DML_D0_Temp_s1_t1.txt 或 20210308_DML_D1_weather_s3_t6.txt,其中 D0/D1 位于哪个文件夹中,温度/天气,无论是温度还是天气文件,s1/s3是位置,t1/t6 是时间点。我想做的第一件事是遍历 D0 和 D1 文件中的 txt 文件,并将名称中包含 Temp 的文件移动到温度子文件夹,并将名称中包含天气的文件移动到 D0 中的天气子文件夹和 D1 文件夹

main Directory
|
|___ weather_day
        ├── D0
           ├── temperature
        │  └── weather
           |__ 20210308_DML_D0_Temp_s1_t1.txt
           |__ 20210308_DML_D1_weather_s3_t6.txt
        └── D1
           ├── temperature
           └── weather
           |__ 20210308_DML_D0_Temp_s1_t1.txt
           |__ 20210308_DML_D1_weather_s3_t6.txt

我尝试使用 for 循环来做到这一点,例如:

wd = getwd() #set working directory to subfolder
pathway = paste0(wd,"/weather_day/")

for (i in pathway){
    file.copy(i,"temperature)
    file.copy(i,"weather")
}

最后我希望txt文件在文件夹中根据他们的名字是否有温度或天气:

main Directory
    |
    |___ weather_day
            ├── D0
               ├── temperature
                        |__20210308_DML_D0_Temp_s1_t1.txt
               └── weather
                        |__ 20210308_DML_D0_weather_s3_t6.txt
            ├── D1
               ├── temperature
                        |__20210308_DML_D1_Temp_s1_t1.txt
               └── weather
                        |__20210308_DML_D1_weather_s3_t6.txt

但是,它对我不起作用。我想我必须使用 file.copy,但是如何使用此函数根据文件的特定名称模式移动文件,并且我可以在 for 循环中使用 for 循环来读取文件夹 D0 和 D1 和那么这些文件夹中的txt文件呢?

【问题讨论】:

    标签: r file movefile


    【解决方案1】:

    您没有提供太多信息。如果我理解您的要求,这应该可以。

    library(tidyverse)
    
    # collect a list of files with their paths
    collector = list.files(paste0(getwd(), "/weather_day"), 
                           full.names = T, # capture the file names along with the full path
                           recursive = T)  # look in subfolders 
    
    # establish the new 'weather' path
    weather = paste0(getwd(), "/weather/")
    
    # establish the new 'temp' path
    temp = paste0(getwd(), "/temp/")
    
    collector = data.frame("files" = collector) %>%    # original path
      mutate(files2 = ifelse(str_detect(str_extract(files, 
                                                    "([^\\/]+$)"),
                                        "weath"),  # if weather, make a new path
                             paste0(weather, 
                                    str_extract(files,
                                                "([^\\/]+$)")
                             ), # end paste0/ if true
                             ifelse(str_detect(str_extract(files,
                                                           "([^\\/]+$)"),
                                               "temp"), # if temp, make a new path
                                    paste0(temp, 
                                           str_extract(files,
                                                       "([^\\/]+$)")
                                    ), # end paste0/ if true
                                    files)    # if not weather or temp, no change
      ) # end if
      ) # end mutate
    
    dir.create(weather)    # create directories
    dir.create(temp)
    
    # move the files
    file.rename(from = collector[,1],
                to = collector[,2])
    
    # validate the change
    list.files(weather) # see what's different
    list.files(temp)    # see what's different
    

    根据@alexdegrote1995 添加的内容,这个怎么样:

    # collect a list of files with their paths
    collector = list.files(paste0(getwd(), "/weather_day"), 
                           full.names = T, # capture the file names along with the full path
                           recursive = T)  # look in subfolders 
    
    # establish the new 'weather' path
    weather = paste0(getwd(), "/D0/weather/")
    
    # establish the new 'temp' path
    temp = paste0(getwd(), "/D0/temperature/")
    
    collector = data.frame("files" = collector) %>% 
      mutate(files2 = ifelse(str_detect(str_extract(files, 
                                                    "([^\\/]+$)"),
                                        "weath"),
                             paste0(weather, 
                                    str_extract(files,
                                                "([^\\/]+$)")
                             ), # end paste0/ if true
                             ifelse(str_detect(str_extract(files,
                                                           "([^\\/]+$)"),
                                               "temp"),
                                    paste0(temp,
                                           str_extract(files,
                                                       "([^\\/]+$)")
                                    ), # end paste0/ if true
                                    files)    # if not weather or temp, don't change
      ), # end if
      filesD1 = paste0(gsub(pattern="D0",          # make a third column for the D1 folder
                            replacement="D1",
                            x =files2,))) # end mutate
    
    
    file.rename(from = collector[,1],  # move files to the D0 folder
                to = collector[,2])
    
    file.copy(from = collector[,2],    # add copy to the D1 folder
              to = collector[,3])
    

    【讨论】:

    • 感谢您的建议。我用我想要的文件夹结构以及文件必须放入的位置稍微更新了我的问题。文件夹天气和温度已经创建。我想遍历 txt 文件,并根据它们的名称中是否有天气或温度,将它们分别放在 D0 和 D1 中的相应文件夹、天气或温度中。
    • 看看我所做的更改是不是你要找的@alexdegrote1995
    • 使用您的代码,我收到一个错误:file.rename(collector[, 1], to = collector[, 2]) 中的错误:'from' 参数无效。这里有什么问题?
    • @alexdegrote1995 我再次运行代码,但没有收到错误消息。你能告诉我dim(collector)的结果吗?您应该有 3 列,它应该是一个数据框。还有其他警告吗?
    • 我确实得到了一个包含三列的数据框,分别称为文件、文件 2 和文件 D1。我得到的数据框有四行。我认为第二行和第三行有问题,因为在第一行和第三行中,我得到了其中的行号(第 1 行中的 1 和第三行中的 3。在第二和第四行中,我得到了一个字符串与“20210308_DML_D0_weather_s3_t6.txt”文件的位置。
    【解决方案2】:

    编辑以包含更多文件名、前置条件(无目录结构)和后置条件。 (加上 move 而不是 copy。)

    files <- c("20210308_DML_D0_Temp_s1_t1.txt", "20210308_DML_D0_weather_s3_t6.txt",
               "20210308_DML_D1_Temp_s1_t1.txt", "20210308_DML_D1_weather_s3_t6.txt")
    # write some temp (empty) files for copying
    for (f in files) writeLines(character(0), f)
    
    parts <- strcapture(".*_(D[01])_([Tt]emp|[Ww]eather)_.*", files, list(d="", tw=""))
    parts
    #    d      tw
    # 1 D0    Temp
    # 2 D0 weather
    # 3 D1    Temp
    # 4 D1 weather
    
    dirs <- do.call(file.path, parts[complete.cases(parts),])
    dirs
    # [1] "D0/Temp"    "D0/weather" "D1/Temp"    "D1/weather"
    
    ### pre-condition, only files, no dir-structure
    list.files(".", pattern = "D[0-9]", full.names = TRUE, recursive = TRUE)
    # [1] "./20210308_DML_D0_Temp_s1_t1.txt"    "./20210308_DML_D0_weather_s3_t6.txt" "./20210308_DML_D1_Temp_s1_t1.txt"   
    # [4] "./20210308_DML_D1_weather_s3_t6.txt"
    
    ### create dirs, move files
    Vectorize(dir.create)(unique(dirs), recursive = TRUE) # creates both D0 and D0/Temp, ...
    #    D0/Temp D0/weather    D1/Temp D1/weather 
    #       TRUE       TRUE       TRUE       TRUE 
    file.rename(files, file.path(dirs, files))
    # [1] TRUE TRUE TRUE TRUE
    
    ### post-condition, files in the correct locations
    list.files(".", pattern = "D[0-9]", full.names = TRUE, recursive = TRUE)
    # [1] "./D0/Temp/20210308_DML_D0_Temp_s1_t1.txt"       "./D0/weather/20210308_DML_D0_weather_s3_t6.txt"
    # [3] "./D1/Temp/20210308_DML_D1_Temp_s1_t1.txt"       "./D1/weather/20210308_DML_D1_weather_s3_t6.txt"
    

    【讨论】:

    • 感谢您的建议。但是,如果我正确理解您的脚本,您将只使用这两个示例文件来移动到地图。那两个只是例子。我的文件比文件夹中结构相似的两个文件多。有没有办法遍历所有文件并将它们移动到 D0 和 D1 中的正确文件夹?
    • 您的解释不太正确,这在 2 或 2000(或更多)上有效,无需担心。唯一的限制是文件名的可解析格式需要一致。用完整的名字向量试试我的电话,如果你有更多问题,请告诉我。
    • 好吧,有趣。代码中的哪里说明了您要查找文件的路径是什么?那是 do.call(file.path) 函数吗?因为当我运行这段代码时,我得到一个错误: dir.create(unique(dirs), recursive = TRUE) 中的错误:无效的“路径”参数
    • 我的错误完全...dir.create 需要矢量化...等待 10 秒,请参阅我的编辑,对此感到抱歉。
    • 使用您的代码,这是输出: [1] "D0/Temp" "D1/weather" D0/Temp D1/weather TRUE TRUE [1] "D0/Temp/20210308_DML_D0_Temp_s1_t1.txt" [ 2] "D1/weather/20210308_DML_D1_weather_s3_t6.txt" [1] FALSE FALSE 好像在主目录下新建了两个文件夹:D0和D1。在 D0 中有一个临时文件夹,在 D1 文件夹中有一个创建的天气文件夹。我用文件夹结构更新了我上面的问题,当前结构是什么以及我真正想要什么。在我的情况下,文件夹温度和天气已经创建。