grep

最近看到 golang 语法中一个非常有趣的基本组合 chan chan ,为了加深自己的理解,想多看几个使用案例,于是去 $GOPATH 下面的文件去找,但是一个个文件找肯定不现实,于是借助 grep 帮我们进行搜索,grep 的使用非常简单,但是如果在不了解 grep 使用的情况下,自己实现一个类似的搜索功能应该也不是很难,今天就让我们来看看 grep 的使用和 golang 版本的简单实现吧。

/usr/bin/grep

grep 命令的基本语法如下所示。

1
2
3
$ grep 'chan' file
$ grep 'chan chan' file1 file2
$ grep [option] 'chan chan' file1 file2

除了列出文件名之外,我们还可以使用通配符搜索当前目录中所有文件。

1
$ grep 'chan chan' *

search sub directories recursively using grep

使用 grep 加上 -r 或者 -R 选项可以递归搜索当前目录下的所有文件。

1
2
$ grep -r 'chan chan' *
$ grep -R 'chan chan' *

examples

例如,以下命令将会输出当前目录中所有文件及其所有子目录中包含单词 chan chan 的每一行。

1
$ grep -r 'chan chan' *

my own grep

如果要自己实现,在不考虑性能的情况下, 只需要实现两个功能,一是文件夹的递归遍历,二就是模式匹配,下面我们实现一个最简单的 grep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var (
haystack = flag.String("path", "", "file path to search in")
needle = flag.String("search", "", "search string to look for")
)

func main() {
flag.Parse()
fi, err := os.Stat(*haystack)
if err != nil {
log.Fatal(err)
}
if fi.Mode().IsDir() {
*haystack = strings.TrimRight(*haystack, "/") + "/"
dfs(*haystack, *needle)
} else {
log.Fatal("path must be a dir")
}
}

我们利用深度优先搜索来遍历相关文件,如果当前对应的 path 为目录( file.Mode().IsDir() ),则递归调用搜索方法,如果 path 为普通文件( file.Mode().IsRegular() ),则利用下面的 grep 方法扫描该文件。直到所有文件均被遍历。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func dfs(path, search string) {
files, err := ioutil.ReadDir(path)
if err != nil {
fmt.Println(err)
}
for _, file := range files {
fullpath := path + file.Name(0
if file.Mode().IsDir() {
dfs(fullpath+"/", search)
} else if file.Mode().IsRegular() {
grep(fullpath, search)
}
}
}

grep individual using scanner

对于每一个 fullpath 对应的文件,我们利用 bufio.NewScanner 构建一个扫描仪,并进行逐行扫描,然后判断要搜索的文字( search )是否存在于该行中,如果存在( strings.Contains ),则在命令行中输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func grep(fullpath, search string) {
f, err := os.Open(fullpath)
if err != nil {
fmt.Println(err)
return
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, search) {
fmt.Println(fullpath, " ", line)
}
}
}
Pieces of Valuable Programming Knowledges