6

我想从特定点递归地遍历目录结构,并在每个级别调用版权更新目录。

Emacs 24 中是否包含有助于解决此问题的功能?例如:

(recursive-directory-walk "~/src/foo" '(copyright-update-directory))

如果不存在这样的功能,那么一些关于开始实现这个(或工作实现)的指针会很棒。

4

5 回答 5

4

MELPA 上的 f.el 库 ( github ) 包含用于文件系统遍历的函数。

(mapc 'copyright-update-directory (f-directories "~/path" nil t))

这将递归地降低目录层次结构。请参阅f-directories的文档。

于 2013-10-22T03:39:52.600 回答
3

不确定是否存在,但不是很难编写自己的。

(defun folder-dirs (folder)
  (delete-if-not 'file-directory-p
    (mapcar (lambda(arg) (file-name-as-directory (concat (file-name-as-directory folder) arg)))
      (delete-if (lambda (arg) (or (string= ".." arg) (string= "." arg)))
        (directory-files folder)))))

(defun recursively-run-on-every-dir (fn folder)
"FN - function, taking one argument; 
FOLDER - initial forder"
  (funcall fn folder)
  (mapc (lambda(arg) (recursively-run-on-every-dir fn arg))
    (folder-dirs folder))
  nil)

;; use your function instead of print
(recursively-run-on-every-dir 'print "/your/initial/path/")
于 2013-01-12T09:39:25.827 回答
2

只需使用find-lisp

(require 'find-lisp)

;;  a simple function, just to test
(defun my-funct (x)
  (princ x)
  (terpri))

(mapc 'my-funct (find-lisp-find-files "~/src/foo/" "\\.txt$"))
于 2013-10-21T20:54:34.383 回答
1

我认为Chris Barrett 的回答是正确且惯用的。但是,出于学习目的,我想实现 Python 的os.walk,一个用于广度优先遍历目录树的通用函数。我使用dash.el了列表库以及f.el文件和目录库。这是从 Python 翻译而来的基于堆栈的实现。

(defun walk (path)
  (let ((stack (list (f-full path)))
        result)
    (while stack
      (let* ((path (pop stack))
             (ds_ (f-directories path))
             (ds (-map 'f-relative ds_))
             (fs (-map 'f-relative (f-files path))))
        (--each ds_ (!cons it stack))
        (!cons (list path ds fs) result)))
    (reverse result)))

见函数:f-full, pop, f-directories, f-relative, f-files, --each, !cons, reverse. 现在你可以在循环中使用它,就像在 Python 中使用它一样:

(loop for (b ds fs) in (walk path)
      do (copyright-update-directory b "*"))
于 2014-03-14T16:34:34.693 回答
1

Emacs 有内置函数directory-files-recursively用于此目的:

(mapc #'YOUR-FUNCTION
      (remove-if-not
       #'file-directory-p       ;only dirs
       (directory-files-recursively YOUR-DIRECTORY "" t)))

它也比另一个答案中提到的f-directories函数快得多,因为它不使用内部递归。

于 2017-08-15T16:03:56.547 回答