有几种方式都能够进入 Dired:
一个 dired buffer 看起来是这样的:

在dired buffer中可以用 n, p, C-n, C-p, <down>, <up> 将光标在各文件/目录间跳转.
当在目录上按下回车键后,会用dired新打开那个目录,而若是在文件上按下回车,则表示用Emacs打开该文件.
除了在 .. 目录上按下回车这种方式可以跳转到上层目录外,dired还提供了一个 ^ 快捷键可以快速地跳转到上层目录中.
另外,在dired buffer中,也能像在普通buffer中那样,使用Emacs的搜索命令来快速定位到指定文件处,这对在含有大量文件的目录中查找指定文件时非常有用.
若你用dired打开某个目录后又手工在Emacs之外对该目录进行了一些操作,比如新增或删除一些文件,dired默认并不会自动刷新内容,这时你可以按下 g 键来强制刷新dired buffer.
在 dired 中,若你需要一次性操作操作文件或者目录,那么你往往需要先mark那些文件/目录,然后再按下对应的操作快捷键对这些文件进行操作.
常见的 mark 命令有这么几个:
由于在dired中的操作并不严格区分文件和目录,因此下面统一用文件代替
当按下操作快捷键时,dired会根据是否有mark的文件来决定该操作是针对光标所在文件进行(当没有mark文件时)的还是针对那些被makr的文件的.
当操作是针对那些被mark的文件时,Emacs一般会列出受影响的文件并提示是否继续该操作.
dired 中对文件的常用的操作有:
除了明确mark出要操作的文件外,还可以使用正则表达式来操作一批文件. 这类使用正则表达式来批量操作的命令一般以 % 号开头:
这其中比较特殊的是 % g, 该命令是根据 文件内容而不是文件名称 来决定是否mark该文件的.
有时,我们可能需要在多个文件中进行搜索/替换操作,那么可以使用如下操作:
dired还允许你调用外部命令来操作文件,这提供了莫大的灵活性:
在输入shell命令操作文件时,可以使用 * 来代替文件列表,这时单独的 * 被替换成被操作的文件,每个文件用空格分隔. 如果需要在命令行中使用通配符 *,则你需要将之用 *"" 来代替,因为对于shell来说,它的作用与 * 一样,而由于 * 并不是独立的,因此不会被替换调.
此外,你还可以使用 . 来代替单个文件,这时单独的 . 被替换成被操作的单个文件,且针对每个文件都会执行一条shell命令.
而倘若输入的命令中并没有函数 * 或者 ., 则表示对每个文件都执行一次shell命令,且文件名被添加到命令的最后.
Emacs还允许你将常用的目录加入书签中,这样你可以很方便的跳回这些目录中.
在dired buffer中按下 C-x r m 就能将当前目录加入到书签中. 默认书签名字就是目录的名称,当然你也可以选择自己喜欢的名字来保存.
然后按下 C-x r l 就能看到弹出一个名为 *Bookmark List* 的buffer,里面列出了所有的书签.
在书签列表中用 n, p,或者 <down>, <up> 将光标移动到要打开的目录处按下回车就会发现Emacs用dired打开那个目录了.
在 *Bookmark List** 中按下 d 可以为书签加上待删除的flag,然后按下 x 就能删掉这些书签了. 这点与dired的操作很类似.
Emacs的书签当然不仅仅这么简单,要了解更多Emacs书签推荐阅读aborn同学的"Emacs的书签功能介绍"
需要说明的是,dired插件本身并不对tar包或者zip包这类打包文件进行特殊处理.
当Emacs打开tar文件时,会进入tar-mode,该mode将整个tar包模拟成了一个目录,并提供了类似dired的操作方式.
对这个tar包进行修改后可以保存这个Tar buffer,更新原来的tar文件.
值得说明的是,Emacs原生支持tar文件,它无需额外的tar程序支持.
类似的,Emacs打开zip,jar,arc,lzh,zoo这类文件时,会进入archive-mode,它将压缩包模拟成一个目录,并提供类似dired的操作方式.
不过这类文件需要调用外部解压程序来进行解压和操纵压缩包里面的文件.
关于这两个命令,推荐看看这篇文件 <Emacs直接编辑压缩打包文件(link:http://aifreedom.com/pluskid/EmacsFileArchives.html)>
如果只是进行文件名的大小写转换,那么dired提供了两个命令专门来实现这一行为:
然而如果要实现更灵活的批量改名,就需要用到dired的正则操作了.
还记得前面提到的 % R, % C, % H 以及 % S 吗?
这几个命令的界面与 replace-regexp 命令的界面是一样的.
当执行这几个命令时,Emacs会提示你先输入一个正则表达式,用于匹配要被操作的那些源文件名称(可以匹配不完整的文件名). 随后你需要再输入一个字符串用于表示目标文件的名称,其中在该字符串中可以使用 \& 表示原正则匹配中的整个匹配内容,用 \N 来表示第N个分组的匹配内容
举个例子,假设你想要将所有后缀为 txt 的文件改名为 org 文件,那么你可以这样操作:
按下 % R,输入 \.txt$ 回车,再输入 \.org$. Emacs会逐个文件地问你是否进行重命名,按 ! 表示对所有文件都执行该操作. 至此所有txt文件都被重命名为org文件了.
不过,使用正则操作虽然能够提供一定的灵活性,但是并没有充分利用Emacs强大的编辑功能. 这个时候就需要请我们的 wired-mode 出场了,它充分的将文件管理与Emacs强大的编辑能力整合起来了.
wdierd允许你通过编辑dired buffer的方式来操作文件.
在dired buffer中按下 C-x C-q 就会进入wdired-mode了. 这时你会发现dired buffer中的文件名部分变得可以编辑了(如果设置了 wdired-allow-to-change-permissions 为t,那么你还能编辑文件属性).
这时你可以使用Emacs的那些编辑功能任意编辑,将文件名称改成你想要的名字. 然后按下 C-c C-c 就会发现文件被重命名成你想要的名字了. 你还可以在文件名中添加路径,这样一来可以实现把文件移动到其他目录中去.
如果你把源文件名称删掉而不提供新名字的化,那么 C-c C-c 后这些文件会被添加上待删除的flag,你只需要再按下 x 就能删掉这些文件了.
若你对这次的改动不满意的话,也可以通过 C-c C-k 取消这次的修改.
使用命令 M-x dired-compare-directories 可以将当前目录与其他目录进行比较并标记出目录间不同的那些文件.
默认情况下dired只根据文件名称来判断文件是否不同. 但其实你可以提供一个任意复杂的lisp表达式来作为判断条件. 任何让该lisp表达式返回非nil的文件都被认为是不相同的. 在这个lisp表达式中可以使用变量 size1 和 size2 来表示两个文件的大小, mtime1 和 mtime2 来表示两个文件的modification time, fa1 和 fa2 表示文件属性列表.
其中后缀为1的变量为当前buffer文件的信息,后缀为2的变量为另一个文件夹中文件的信息.
dired提供了多种方式打开文件:
上面这些命令,都只会打开光标所在的文件(而不管是否已经mark了多个文件),而且都是使用Emacs本身来打开文件的.
不过Emacs本身支持文本文件,图片文件以及pdf文件,因此一般来说用Emacs打开文件也足够了.
若需要使用外部程序来打开文件,则需要使用 ! 或 & 命令. 一般来说,对于linux用户可以使用 xdg-open 这个程序来使用默认的打开方式打开文件.
Xah大神专门针对用外部程序打开文件写过一篇博文,有兴趣的同学可以看一下: Emacs:Open File in External App(link:http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html)
dired-x为dired增加了很多方便的功能,比较常用的有:
此外dired-x也会增强原dired已有的功能:
在没有mark文件的情况下使用 ! 或 &,则Emacs会依据变量 dired-guess-shell-alist-default 中定义的规则来猜测你要对该文件作什么操作.
例如,针对tar文件按下 !, 它会自动帮你填上 tar xvf 命令.
细心的同学应该会注意到dired buffer中的内容其实就是 ls -l 产生的结果.
我们可以自定义传递给 ls 的参数以此产生排序的效果.
按下 C-u s,会在minibuffer中显示 ls switches (must contain -l): -al, 我们在这里修改传递给 ls 的参数.
修改参数为 -alS 表示结果会按照大小排序,修改参数为 -alSr 表示按大小逆向排序.
当然,由于按时间排序这个功能太常见了,你可以直接按 s 进行排序,按第一次按时间先后进行排序,再按一次则变成按时间先后逆向排序.
若需要过滤掉一些不关心的文件(比如.svn,.git文件夹等),可以先mark那些要隐藏的文件(可以使用正则表达式一次mark一批文件),然后按下 k 隐藏掉这些文件.
若大家觉得不方便的话,dired-x还提供了一个 dired-omit-mode,能够自动隐藏调你想屏蔽的文件.
在启动 dired-omit-mode 前,你通常需要配置一下 dired-omit-files 和 dired-omit-extensions 这两个变量.
其中 dired-omit-files 是一个正则表达式,任何名称匹配该正则表达式的文件将被隐藏.
而 dired-omit-extensions 则是一个字符串列表,任何文件后缀在这个列表中的文件也都会被隐藏.
分色是指让不同类型的文件用不同颜色标注出来.
虽然dired本身并不支持分色,但是借助 highlight-lines-matching-regexp 命令,我们很容易可以实现该功能.
假设我们想把所有org文件用黄色标注出来,那么可以这样做:
当然你也可以通过 dired-mode-hook 让这一分色过程自动化:
(add-hook 'dired-mode-hook
(lambda ()
(highlight-lines-matching-regexp "\.org$" 'hi-yellow)))
这样一来,每次进入dired,都会自动将org文件标注为黄色.

若同时想对多个目录下的文件进行操作该怎么办呢?在目录上按下 I 快捷键就能将该子目录的内容插入到当前同一个 dired buffer 中,例如假设我有这么一个文件夹:
/home/lujun9972/github/lujun9972.github.com/Emacs之怒/ /home/Administrator/lujun9972.github.com:
总用量 117
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:50 .
drwxrwxrwx+ 1 Administrator None 0 十二 8 15:50 ..
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:29 .git
-rw-r--r-- 1 Administrator None 187 十一 24 17:36 .travis.yml
-rw-r--r-- 1 Administrator None 80 十一 24 17:36 about.org
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:48 Emacs之怒
drwxr-xr-x+ 1 Administrator None 0 十二 5 12:58 linux和它的小伙伴
-rw-r--r-- 1 Administrator None 238 十一 24 17:36 README
-rw-r--r-- 1 Administrator None 61440 十二 8 15:18 test.tar
drwxr-xr-x+ 1 Administrator None 0 十一 24 17:36 编程之旅
lrwxrwxrwx 1 Administrator None 36 十一 24 17:36 读书笔记 -> /home/lujun9972/我的笔记/Reading
drwxr-xr-x+ 1 Administrator None 0 十一 24 17:36 时间管理
drwxr-xr-x+ 1 Administrator None 0 十一 24 17:36 无主之地
当我将光标移动到 Emacs 之怒 上然后按下 i 键时,就变成了:
/home/Administrator/lujun9972.github.com:
总用量 117
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:50 .
drwxrwxrwx+ 1 Administrator None 0 十二 8 15:50 ..
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:29 .git
-rw-r--r-- 1 Administrator None 187 十一 24 17:36 .travis.yml
-rw-r--r-- 1 Administrator None 80 十一 24 17:36 about.org
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:48 Emacs之怒
drwxr-xr-x+ 1 Administrator None 0 十二 5 12:58 linux和它的小伙伴
-rw-r--r-- 1 Administrator None 238 十一 24 17:36 README
-rw-r--r-- 1 Administrator None 61440 十二 8 15:18 test.tar
drwxr-xr-x+ 1 Administrator None 0 十一 24 17:36 编程之旅
lrwxrwxrwx 1 Administrator None 36 十一 24 17:36 读书笔记 -> /home/lujun9972/我的笔记/Reading
drwxr-xr-x+ 1 Administrator None 0 十一 24 17:36 时间管理
drwxr-xr-x+ 1 Administrator None 0 十一 24 17:36 无主之地
/home/Administrator/lujun9972.github.com/Emacs之怒:
总用量 77
drwxr-xr-x+ 1 Administrator None 0 十二 8 16:03 .
lrwxrwxrwx 1 Administrator None 33 十二 8 16:03 .#dired的常用操作.org -> Administrator@PC201505171055.5772
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:50 ..
-rw-r--r-- 1 Administrator None 6981 十二 8 16:02 dired的常用操作.org
-rw-r--r-- 1 Administrator None 9213 十一 24 17:36 Emacs查看日志常用命令.org
-rw-r--r-- 1 Administrator None 10881 十一 24 17:36 Emacs中那些不常用的行操作命令.org
-rw-r--r-- 1 Administrator None 5507 十一 24 17:36 Emacs作为图片浏览器.org
-rw-r--r-- 1 Administrator None 3226 十一 24 17:36 tramp的一般用法.org
-rw-r--r-- 1 Administrator None 2522 十一 24 17:36 判断Emacs是否在图形环境中的正确方法.org
-rw-r--r-- 1 Administrator None 11115 十一 29 11:30 如何编写EmacsScript.org
-rw-r--r-- 1 Administrator None 1524 十一 24 17:36 使用Emacs ediff作为git diff工具.org
-rw-r--r-- 1 Administrator None 1791 十一 24 17:36 使用Emacs ediff作为git merge工具.org
这样一来你就可以同时操作多个目录中的文件了,你还可以使用 $ 来将目录折叠/舒展开来,dired 中的那些命令会忽略调折叠起来的内容。
例如我在 lujun9972.github.com 目录内容中的任意位置处按下 $,则会发现 dired buffer 变成了
/home/Administrator/lujun9972.github.com:...
/home/Administrator/lujun9972.github.com/Emacs之怒:
总用量 77
drwxr-xr-x+ 1 Administrator None 0 十二 8 16:03 .
lrwxrwxrwx 1 Administrator None 33 十二 8 16:03 .#dired的常用操作.org -> Administrator@PC201505171055.5772
drwxr-xr-x+ 1 Administrator None 0 十二 8 15:50 ..
-rw-r--r-- 1 Administrator None 6981 十二 8 16:02 dired的常用操作.org
-rw-r--r-- 1 Administrator None 9213 十一 24 17:36 Emacs查看日志常用命令.org
-rw-r--r-- 1 Administrator None 10881 十一 24 17:36 Emacs中那些不常用的行操作命令.org
-rw-r--r-- 1 Administrator None 5507 十一 24 17:36 Emacs作为图片浏览器.org
-rw-r--r-- 1 Administrator None 3226 十一 24 17:36 tramp的一般用法.org
-rw-r--r-- 1 Administrator None 2522 十一 24 17:36 判断Emacs是否在图形环境中的正确方法.org
-rw-r--r-- 1 Administrator None 11115 十一 29 11:30 如何编写EmacsScript.org
-rw-r--r-- 1 Administrator None 1524 十一 24 17:36 使用Emacs ediff作为git diff工具.org
-rw-r--r-- 1 Administrator None 1791 十一 24 17:36 使用Emacs ediff作为git merge工具.org
你会发现 lujun9972.github.com 中的内容被简化成了 ...
如果你希望把某个子目录给删掉,可以在子目录的头部按下 C-u k,你会发现内容变成了:
/home/lujun9972/github/lujun9972.github.com/Emacs之怒:
/home/Administrator/lujun9972.github.com:...
子目录的内容都被删除了。

