如何获取目录中的目录列表,例如list.files(),而是“ list.dirs()”


77

对于某人来说,这可能是一个非常简单的问题-我可以使用它list.files()来获取给定目录中的文件列表,但是如果我想获取目录列表,我该怎么做?作为我的选择,它摆在我面前list.files()吗?

另外,我正在使用Windows,因此,如果答案是要使用Linux / unix命令,那对我来说将不起作用。

例如Directory.GetFiles(),.NET有一个方法和一个单独的Directory.GetDirectories() 方法,所以我认为R具有类似的对。提前致谢。

Answers:


110

更新:list.dirs2011年4月发布的R-2.13.0版本中向版本54353的基本程序包中添加了一个功能。

list.dirs(path = ".", full.names = TRUE, recursive = TRUE)

所以我下面的功能只用了几个月。:)


我找不到执行此操作的基本R函数,但是使用以下代码编写自己的函数将非常容易:

dir()[file.info(dir())$isdir]

更新:这是一个函数(现已针对蒂莫西·琼斯的评论进行了更正):

list.dirs <- function(path=".", pattern=NULL, all.dirs=FALSE,
  full.names=FALSE, ignore.case=FALSE) {
  # use full.names=TRUE to pass to file.info
  all <- list.files(path, pattern, all.dirs,
           full.names=TRUE, recursive=FALSE, ignore.case)
  dirs <- all[file.info(all)$isdir]
  # determine whether to return full names or just dir names
  if(isTRUE(full.names))
    return(dirs)
  else
    return(basename(dirs))
}

两次调用dir()的格式错误-两次调用之间可能会发生变化(是的,p = 0.0000001),但仍然……有一天!
Spacedman 2011年

@Spacedman-我同意,它更像是一种概念证明。查看我的更新。
约书亚·乌尔里希

您将需要从中删除递归参数,否则您的函数将无法工作。在这种情况下,list.filesdir没有列出它发现作为单独的“文件”的任何目录,而是,R列出的任何文件中发现的目录。由于所有这些都是文件而不是目录,因此您的函数返回的向量为NA
Gavin Simpson

实际上,我确实确实得到了NA的向量...我将尝试另一种方法
user297400 2011年

很有用。好的答案
Rich Scriven 2014年

31

baseR现在包含一个list.dirsfunction,因此不再需要自制的变体。

例如:

list.dirs('.', recursive=FALSE)

为+1 recursive = FALSE,否则将列出当前目录(。)和子目录中的目录。
Chintan Pathak

18

只是为了更新此线程:

我看到在R的较新版本中(当前我使用的是2.5.1),list.dirs基本安装中现在包含一个函数:

list.dirs隐式具有all.files = TRUE,如果递归= TRUE,则答案包括路径本身(假设它是可读目录)。


您是否使用过内置功能?我无法all.files=TRUE上班,只是没有显示完整的路径。
AnjaM 2012年

是的,现在接受的答案已经过时。list.dirs()是现在获得此的最佳方法。
rensa

8
list.dirs <- function(...) {
    x <- dir(...)
    x[file_test("-d", x)]
}

可能有用吗?

我们怎么可能递归地做到这一点?(recursive参数参数dir破坏了这些功能,因为它从不返回目录名,仅返回每个目录中的文件,等等)。


这也不起作用,但感谢您的回答。我将一直使用file.info和$ dir直到找到有效的东西
user297400 2011年

3
@ user297400如果它对您不起作用,则不应接受我的回答正确。
约书亚·乌尔里希

2

您提到您不想使用Linux / UNIX命令,但是我认为可以使用Windows命令。在这种情况下,可以这样做:

shell("dir/ad/b", intern = TRUE)

这将递归执行:

shell("dir/ad/b/s", intern = TRUE)

通常,在这里我更喜欢其他平台无关的解决方案,但特别是在交互使用时,您只关心尽可能简单直接地获得答案,这可能会减少工作量。


2

像这样的东西怎么样,试试看:

dir('.')[file.info(dir('.',full.names=T))$isdir]

-1

我前一段时间遇到这个问题,并使用此递归代码查找所有目录。也许这有用吗?

list.dirs <- function(parent=".")   # recursively find directories
{
    if (length(parent)>1)           # work on first and then rest
        return(c(list.dirs(parent[1]), list.dirs(parent[-1])))
    else {                          # length(parent) == 1
        if (!is.dir(parent))
            return(NULL)            # not a directory, don't return anything
        child <- list.files(parent, full=TRUE)
        if (!any(is.dir(child)))
            return(parent)          # no directories below, return parent
        else 
            return(list.dirs(child))    # recurse
    }
}

is.dir <- function(x)    # helper function
{
    ret <- file.info(x)$isdir
    ret[is.na(ret)] <- FALSE
    ret
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.