如何使用R重命名文件?

78

我有一个文件夹里面有超过700个文件,它们的命名方式是这样的: 前九个文件是按照数字1到9命名的,代表第一个月:

water_200101_01.img  
water_200101_09.img  

编号为10至30的文件命名如下:

water_200101_10.img
water_200101_30.img

接下来是第二个月的情况: 编号从1到9的文件名为:

water_200102_01.img  
water_200102_09.img  

编号从10到30的文件名为:

water_200102_10.img
water_200102_30.img 

如何在不改变文件的情况下重命名它们,只需更改名称,例如:

water_1
water_2
...till...
water_700

非常类似于https://dev59.com/NVzUa4cB1Zd3GeqP3n_x - Andrie
4个回答

110

file.rename可以重命名文件,它可以接受一个包含要从哪个名称到哪个名称的向量。

因此,像这样:

file.rename(list.files(pattern="water_*.img"), paste0("water_", 1:700))

可能有效。

如果你特别关注文件的顺序,你可以对当前存在的文件列表进行排序,或者如果它们遵循特定的模式,直接创建文件名向量(尽管我注意到700不是30的倍数)。

我会放下为什么要这样做的问题,因为你似乎在文件名中丢失了信息,但是假设那些信息也存在于其他地方。


4
在注释中读取错误很困难。看起来dir2保存了需要重命名的文件的名称,所以它应该是file.rename的第一个参数(而不是另一个list.files调用)。而且,在file.rename内部的list.files调用的末尾缺少一个闭合括号。 - Brian Diggs
嗨@Brian,当我做类似的事情时,我收到了“FALSE”消息。文件无法被重命名。由tmp_rename命名的目标文件夹包含三个随机文件。这是我的代码list.files('tmp_rename') %>% file.rename(to = c('a','b','c')) - Jiaxiang
喜欢你的解决方案,但遗憾的是,你的解决方案似乎不适用于UTF8编码的文件名,例如: "קובץ מספר 1.xls" "קובץ מספר 2.xls" "קובץ מספר 3.xls" - amann

8
我为自己写了这个程序。它快速、允许在查找和替换中使用正则表达式,可以忽略文件后缀,并且可以显示“试运行”中会发生什么以及保护现有文件不被覆盖。
如果您使用的是Mac,它可以使用AppleScript在Finder中选择当前文件夹作为目标文件夹。
umx_rename_file <- function(findStr = "Finder", replaceStr = NA, baseFolder = "Finder", test = TRUE, ignoreSuffix = TRUE, listPattern = NULL, overwrite = FALSE) {
    umx_check(!is.na(replaceStr), "stop", "Please set a replaceStr to the replacement string you desire.")

    # ==============================
    # = 1. Set folder to search in =
    # ==============================
    if(baseFolder == "Finder"){
        baseFolder = system(intern = TRUE, "osascript -e 'tell application \"Finder\" to get the POSIX path of (target of front window as alias)'")
        message("Using front-most Finder window:", baseFolder)
    } else if(baseFolder == "") {
        baseFolder = paste(dirname(file.choose(new = FALSE)), "/", sep = "") ## choose a directory
        message("Using selected folder:", baseFolder)
    }

    # =================================================
    # = 2. Find files matching listPattern or findStr =
    # =================================================
    a = list.files(baseFolder, pattern = listPattern)
    message("found ", length(a), " possible files")

    changed = 0
    for (fn in a) {
        if(grepl(pattern = findStr, fn, perl= TRUE)){
            if(ignoreSuffix){
                # pull suffix and baseName (without suffix)
                baseName = sub(pattern = "(.*)(\\..*)$", x = fn, replacement = "\\1")
                suffix   = sub(pattern = "(.*)(\\..*)$", x = fn, replacement = "\\2")
                fnew = gsub(findStr, replacement = replaceStr, x = baseName, perl= TRUE) # replace all instances
                fnew = paste0(fnew, suffix)
            } else {
                fnew = gsub(findStr, replacement = replaceStr, x = fn, perl= TRUE) # replace all instances
            }
            if(test){
                message(fn, " would be changed to:  ", omxQuotes(fnew))
            } else {
                if((!overwrite) & file.exists(paste(baseFolder, fnew, sep = ""))){
                    message("renaming ", fn, "to", fnew, "failed as already exists. To overwrite set T")
                } else {
                    file.rename(paste0(baseFolder, fn), paste0(baseFolder, fnew))
                    changed = changed + 1;
                }
            }
        }else{
            if(test){
                # message(paste("bad file",fn))
            }
        }
    }
    if(test & changed==0){
        message("set test = FALSE to actually change files.")
    } else {
        umx_msg(changed)
    }
}

8
如果您想用另一种模式替换与给定模式匹配的文件名的某个部分,则可以使用这种方法。这对于批量重命名多个文件非常有用。例如,此代码将获取所有包含“foo”的文件,并在文件名中将“foo”替换为“bob”。
file.rename(list.files(pattern = "foo"), str_replace(list.files(pattern = "foo"),pattern = "foo", "bob"))

3
以下是我在指定目录中匹配并按顺序更改所有文件名的解决方法,使用了简单的基础代码。
old_files <- list.files(path = ".", pattern="water_*.img$")

# Create df for new files
new_files <- data.frame()

for(i in 1:length(old_files)){
new_files <- append(paste0(path = ".", substr(old_files[i], 1,6),"water_",i,".img"), new_files)
}

new_files <- as.character(new_files)

# Copy from old files to new files

file.rename(from = old_files), to = as.vector(new_files)

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