对话 UNIX,第 7 部分: 命令行惯用语

Unix?具有自己的方言,并且其命令词汇表非常庞大 。但是您并不需要一次掌握所有的内容 。本文介绍了许多命令行组合,可以促进您对 UNIX 语言的掌握 。
当您到使用不同语言的国家去旅行时,可能需要掌握一些关键的日常用语,如“这个东西多少钱?、“这是什么肉?以及“洗手间在何处? 。记住这些简短的日常用语可以确保别人不会对您定购的三明治要价太高,并且在需要上厕所的时候,您知道该去何处 。
UNIX?也具有自己的方言,在过去的 6 个月中,这个对话 UNIX 系列为 UNIX 命令行惯用语提供了速成教程 。这个月我们将介绍一些有用的短语,它们能够使您立即成为地道的 UNIX 用户 。带上牙刷,穿上舒适的鞋子,并且更新您的惯用语 。我们要出门迎接阳光、沙滩和贝壳 。(置身于阳光和沙滩中,面朝海滩,打开便携式计算机,然后阅读本专栏 。可不要忘了抹点防晒油 。)
开始学习之旅
在以前的对话 UNIX 专栏(请参见参考资料部分)中曾多次介绍了 find 命令,这是一种非常有用的实用工具,可用于扫描并处理各种文件,甚至整个 UNIX 文件系统 。例如,我经常将 find 与 grep 或者 Perl 一起使用,以便对大量的文件进行处理 。您需要了解在一大段代码中的何处定义了变量或常量吗?可以尝试下面的命令:
$ find /path/to/src
-type f | xargs grep -H -I -i -n
string
该命令的输出是一个文件名列表,其中包含 string,包括行编号和匹配的特定文本 。在每个匹配的文件名和行编号的前面分别加上了 -H 和 -n 选项 。-i 选项忽略大小写 。-I(大写“I)跳过二进制文件 。
您以前可能没有见过 xargs,它将使用列出的所有选项运行您所指定的命令,在本示例中是 grep,每次使用通过标准输入提供的一个参数 。假设 /path/to/src 目录包含文件 a、b 和 c,使用 find 与 xargs 等价于:
grep -H -I -i -n string a
grep -H -I -i -n string b
grep -H -I -i -n string c
事实上,搜索文件集是一项常见的工作,所以 grep 具有相应的选项以递归遍历整个文件系统层次结构 。可以使用 -d recurse 或其同义词 -R 或者 -r 。例如,可以使用:
$ grep -H -I -i -n -R string
/path/to/src
这个命令与 find/xargs 完成相同的任务 。(您将发现,许多与文件相关的 Unix 实用工具都具有递归选项 。ls -R 可以递归地列出层次结构中的内容 。chmod、chgrp 和 chown 使用 -R 可以递归地将模式、组和所有权变更应用到整个文件系统层次结构 。在使用 chmod -R 时,请多加小心 。如果删除了目录的执行位,比如 chmod -R a-x,您可能会使得一个目录变得不可使用 。为了更具选择性,可以使用 find . -type f | xargs chmod a-x 。)
那么,什么时候应该使用 find/xargs,什么时候应该使用 grep 呢?当需要具有一定的选择性时,可以使用 find 。find 命令具有许多选项,使得您可以选择满足特定要求的文件,如“所有在午夜后修改过的、并由 Joe 拥有的常规文件 。否则,使用 grep -R 就可以了 。
另一种实用工具可能比 find 使用起来更加方便,并且速度更快 。如果您打算根据名称来查找一个文件,那么可以尝试使用 locate 来代替 find -name 。locate 命令周期性地(大约每天一次,由系统管理员设置)为系统中所有的文件编制目录,并构建一个由路径和文件名组成的数据库 。当您运行 locate 时,它将扫描其私有的数据库,尝试进行匹配 。
例如,运行查询 locate '*.1',将得到名称以 .1 结尾的所有文件和目录 。(前面的星号表示匹配任何字符串 。)为了方便起见,运行 locate fish 命令与运行 locate '*fish*' 是相同的 。

推荐阅读