想在当前目录及子目录的.cpp文件中搜索关键字char,键入:
grep -R char *.cpp
失败。
找了很久原因,发现这样一个事实:
-R选项的确会进入子目录递归匹配,但前提是,子目录名称也必须满足*.cpp的命名规则,也就是说,对于如下目录层次应用上面的命令:
./1.cpp
./2.cpp
./dir.cpp/3.cpp
./dir/4.cpp
其中./dir/4.cpp由于目录名称不满足*.cpp的命名规则,4.cpp这个文件是不会参与匹配的...
正确的方案得引入管道:
find -type f -name *.cpp | xargs grep char
由于我自己的应用场合不太适合管道,最终降低要求,改为匹配包括.cpp在内的所有文件:
grep -R char *
另外,grep的行为不符合我这个Windows程序员直觉的地方其实有两点(不同于Windows下findstr /S char *.cpp):
1. 开启-R后,只有顶层子目录名满足规则才会深入该目录递归。针对我文章开头的命令,文件./cpp/1.cpp的内容会进行匹配,而文件./dir/2.cpp不会进行匹配。
2. 开启-R后,一旦顶层子目录名满足规则,则其下的各级更深层次的子文件不再受命名规则限制,直接进入内容匹配的环节。即./cpp/1.txt和./cpp/dir/2.txt的内容都会进行匹配。
总结:
grep -R char *.cpp中的命名规则*.cpp,是用来约束顶层子目录和子文件的,通过过滤的顶层子目录,其下所有更深层的子文件均算通过名称过滤。
相对的,Windows下findstr /S char *.cpp,其中的*.cpp是用来约束所有深度子文件名的,而各级子目录无条件遍历(个人觉得这种行为更自然)。