File Emacs lisp:不带“目录文件”而获取“目录文件”的简洁方法&引用;及"&引用;?

File Emacs lisp:不带“目录文件”而获取“目录文件”的简洁方法&引用;及"&引用;?,file,emacs,directory,elisp,interactive,File,Emacs,Directory,Elisp,Interactive,函数目录文件还返回和。条目。从某种意义上说,函数只以这种方式返回所有现有条目是正确的,但我还没有看到包含这些条目的用途。另一方面,每次使用目录文件时,我也会编写类似 (unless (string-match-p "^\\.\\.?$" ... 还是为了更好的效率 (unless (or (string= "." entry) (string= ".." entry)) ..) 特别是在交互式使用(M-:)中,额外的代码是不可取的 是否有一些预定义函数可以有效

函数
目录文件
还返回
条目。从某种意义上说,函数只以这种方式返回所有现有条目是正确的,但我还没有看到包含这些条目的用途。另一方面,每次使用
目录文件时,我也会编写类似

(unless (string-match-p "^\\.\\.?$" ... 
还是为了更好的效率

(unless (or (string= "." entry)
            (string= ".." entry))
   ..)
特别是在交互式使用(
M-:
)中,额外的代码是不可取的


是否有一些预定义函数可以有效地只返回目录的实际子项?

您可以在原始函数调用中执行此操作

(directory-files DIRECTORY &optional FULL MATCH NOSORT)

If MATCH is non-nil, mention only file names that match the regexp MATCH.
因此:

(目录文件(展开文件名“~/”)nil“^\([^.]\\\\\\\\\\\\\\\.\\\.\\\\.\\\\.\\\\\\))
或:

(删除我的目录文件(目录和可选完整nosort)
“像‘目录文件’,匹配硬编码为排除\”“和\”“。\”
(目录文件目录已满“^\\([^.]\\\\\\\\\\\.\\\\\\\\.\\\..\)“nosort))
尽管与您自己的方法更相似的东西可能会使包装更有效,真的

(取消我的目录文件(目录和可选完全匹配nosort)
与“目录文件”类似,但不包括\“\”和\.\”
(删除“.”(删除“.”(目录文件目录完全匹配nosort)))
虽然这会对列表进行两次处理,而且我们知道我们希望排除的每个名称只有一个实例(它们很可能会首先出现),因此,如果您希望频繁处理大型目录,这样的解决方案可能是一个很好的解决方案:

(取消我的目录文件(目录和可选完全匹配nosort)
与“目录文件”类似,但不包括\“\”和\.\”
(让*((文件(cons nil(目录文件目录完全匹配nosort)))
(父文件)
(当前(cdr文件))
(排除(列表“.”)
(档案无)
(while(和当前排除)
(setq文件(车辆电流))
(如果(不是(成员文件排除))
(setq母电流)
(设置cdr父级(cdr当前))
(setq排除(删除文件排除)))
(setq电流(cdr电流)))
(cdr文件)
如果您使用一个方便的文件和目录操作库,您只需要函数

但是,如果出于某种原因不想使用此库,并且可以使用非便携*nix解决方案,则可以使用

上面的代码就足够了,但要进一步解释,请阅读

去掉圆点 根据:

通过将字符串按空格拆分,我们可以解析
ls
输出:

(split-string (shell-command-to-string "ls -A"))
文件名中的空格 问题是某些文件名可能包含空格<代码>拆分字符串
默认情况下按变量中的正则表达式进行拆分,变量为[\f\t\n\r\v]+”

-1
允许以换行符分隔文件,将
“\n”
作为唯一分隔符传递。您可以将其包装在函数中,并将其用于任意目录

(split-string (shell-command-to-string "ls -A1") "\n")
递归 但是,如果您想递归地深入到子目录中,返回文件以供将来使用,该怎么办?如果您只是更改目录并发出
ls
,您将获得没有路径的文件名,因此Emacs不知道这些文件位于何处。一种解决方案是使
ls
始终返回绝对路径。根据
手册ls

   -d, --directory
          list directory entries instead of contents, and do not dereference symbolic links
如果您使用通配符和
-d
选项将绝对路径传递到目录,那么您将获得即时文件和子目录的绝对路径列表,根据。有关路径构造的说明,请参见

省略空字符串 Unix命令必须在输出中添加一个尾随空格,以便提示符位于新行。否则,而不是:

user@host$ ls
somefile.txt
user@host$
将有:

user@host$ ls
somefile.txtuser@host$

当您将自定义分隔符传递给
拆分字符串
时,它会将此换行单独视为一行。通常,这允许正确解析CSV文件,其中空行可能是有效数据。但是对于
ls
我们最终得到了一个空字符串,通过将
t
作为第三个参数传递给
split string

应该忽略它。因此,没有简单的内置代码可用?您可以使用
(目录文件“~/”t目录文件无点文件regexp)得到相同的结果。
@斯奎特您的答案是最好的,但没有人看到它。
(成员条目“(““…”)
是测试字符串是否等于一组固定元素中的一个的更好方法。这一点很好。我刚刚对它进行了基准测试,除了更易于阅读之外,
成员
版本比
(或(字符串=…))版本快20%左右
version。在这种情况下,使用regexp比较较慢。即使使用
目录文件
MATCH
参数,也不会更快——因此更通用的方法是在之后使用
过滤输出(delete nil(mapcar..
使用
成员
,这样可以避免混淆
匹配
参数,总体上更好。至少如果一个人决定使用自定义函数而不是直接使用
目录文件
(我现在这样做)。这不是最好的答案,最好的答案是下面使用
(目录文件)/tmp“t目录文件无点文件(regexp)
   -d, --directory
          list directory entries instead of contents, and do not dereference symbolic links
(let ((path (file-name-as-directory (expand-file-name d))))
  (split-srting (shell-command-to-string (concat "ls -A1d " path "*")) "\n"))
user@host$ ls
somefile.txt
user@host$
user@host$ ls
somefile.txtuser@host$