Grep

Grep

中等

简介

你在当地一家图书馆找了份工作,帮忙整理馆藏的旧书。常来的学生读者常常要翻找那些记不全的引文,好写进自己的学期论文里。与其一本一本地从头读到尾,你决定做一个小工具来扫描这些书,找出那些残缺的引文。

说明

在文件中搜索与搜索字符串匹配的行,并返回所有匹配的行。

Unix 的grep命令会在文件中搜索匹配正则表达式的行。你的任务是实现一个简化版的grep命令,它支持搜索固定字符串。

grep命令接受三个参数:

  1. 要搜索的字符串。
  2. 零个或多个用于自定义命令行为的标志。
  3. 一个或多个要搜索的文件。

然后它会按指定的顺序读取这些文件的内容,找出包含搜索字符串的行,最后按找到它们的顺序返回这些行。在多个文件中搜索时,每条匹配的行前面都会加上文件名和一个冒号(':')。

标志

grep命令支持以下标志:

  • -n在输出的每一行前面加上行号和冒号(':'),并把行号放在文件名之后(如果有文件名的话)。
  • -l只输出至少包含一条匹配行的文件名。
  • -i使用不区分大小写的比较进行匹配。
  • -v反转程序,即收集所有不匹配的行。
  • -x只搜索搜索字符串与整行完全匹配的行。

错误处理

这个练习会介绍anyhow crate,它能让你轻松处理各种错误类型。它的用意是:写应用程序时,你不必操心被调用的函数返回的究竟是哪种具体错误,只需在传播错误时处理得当即可。

注意:在编写库时(就像我们这里这样)使用anyhow其实不太妥当;编写库时,自己写一个Error枚举会更明确、也更有用(可以借助thiserror crate之类的辅助宏)。不过,我们在这里是有意这么做的,目的就是演示这个 crate 的用法。

想进一步了解这个 crate,请参考它的文档。

延伸阅读

虽然这个练习只要求你实现grep最基本的功能,但实际上有一个用 Rust 完整重新实现grep的项目:ripgrep。

如果你喜欢用 Rust 重写这些基础工具程序的想法,不妨看看下面这些项目:

  • fd:find的克隆
  • exa:ls的克隆
  • bat:cat的克隆
  • coreutils:GNU coreutils 的重写版
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Rust Exercism

准备好开始 Grep 了吗?

注册 Exercism,借助 99 个练习 和真人导师指导,学习并掌握 Rust,全部免费。