在 emacs dired 中,如何对多个标记文件运行命令?

在 emacs dired 中,如何对多个标记文件运行命令?

我有几个以 dired 模式标记的文件,我想对(delete-trailing-whitespace)它们每个运行一个命令。

是否有内置方法可以做到这一点,还是我需要自己编写?

基本上我想做类似的事情(dired-do-shell-command),但我想评估 emacs 表达式而不是 shell 命令。我想在 emacs 中对我标记的文件执行此操作,所以我不能使用-batch

答案1

我写了一些东西来做我想做的事情,以防其他人发现它有用:

更新:使用更通用的命令更新了此解决方案。

(defun mrc-dired-do-command (command)
  "Run COMMAND on marked files. Any files not already open will be opened.
After this command has been run, any buffers it's modified will remain
open and unsaved."
  (interactive "CRun on marked files M-x ")
  (save-window-excursion
    (mapc (lambda (filename)
            (find-file filename)
            (call-interactively command))
          (dired-get-marked-files))))

现在M-x mrc-dired-do-command delete-trailing-whitespace做我想做的事。

如果有人指出我没有必要这样做并且我忽略了像这样的明显的命令,我会很高兴dired-do-command

答案2

据我所知,dired 没有这样的功能,但 ibuffer 有——使用 dired 标记您想要影响的所有文件(m)、访问它们(C-u F)、运行 ibuffer(M-x ibuffer [RET])、标记所有缓冲区(m)并调用ibuffer-do-evalE)、在每个缓冲区中插入您想要评估的表达式、保存它们全部(S)并关闭它们(D)。

答案3

这并不是您所要求的,但您可以在 ibuffer 中标记缓冲区并使用“E”(ibuffer-do-eval FORM)

我知道 eshell 允许您使用 elisp 进行 shell 脚本编写(有点),所以您可能可以更轻松地从 eshell 完成此操作。

答案4

Matt 的解决方案很有用,但它有点受限,因为它只允许执行单个命令而不带任何参数。我想知道是否有可能在标记的文件上执行宏,并想出了以下 dired 命令,它允许为每个选定文件重放任何(已保存的)宏任意次数。

通过这个命令,我终于能够以相当简单的方式半自动地编辑许多文件!

更新:新版本允许执行任意命令(包括宏)和 lisp 表达式。

;; Inspired by M-x edit-kbd-macro and https://superuser.com/q/176627.
(defun my-dired-do-execute (keys &optional arg)
  "Execute a command in all marked files.
If an error occurs, execution in other files is not affected.
(Notably, this allows to run keyboard macros until there is an error.)

At the prompt, type any bound key sequence, or `\\[execute-extended-command]'
to choose a command by its name, or `\\[eval-expression]' to enter a Lisp expression.

The prefix ARG, if given, is passed on to the chosen command.
"
  (interactive
   (list (read-key-sequence (substitute-command-keys "Key sequence to execute, \
or \\[eval-expression], or \\[execute-extended-command]: "))
         current-prefix-arg))
  (when keys
    (let ((cmd (if (arrayp keys) (key-binding keys) keys))
          exp)
      (cond ((eq cmd 'execute-extended-command)
             (setq cmd (read-command "Name of command to execute: "))
             (if (string-equal cmd "")
                 (error "No command name given")))
            ((eq cmd 'eval-expression)
             (setq exp (read--expression "Eval in selected files: "))
             (setq cmd nil))
            ((null cmd)
             (error "Key sequence %s is not defined" (key-description keys))))
      (mapc (lambda (filename)
              (save-selected-window
                (find-file-other-window filename)
                (setq current-prefix-arg arg)
                (condition-case-unless-debug err
                    (if cmd
                        (call-interactively cmd)
                      (message "Result in file %s:" filename)
                      (eval-expression exp))
                  (error (message "In file %s: %S" filename err)))))
            (dired-get-marked-files)))))

相关内容