grep与管道

管道与grep查询

今天麟遇到一个问题让我学到很多东西。他想在当前目录及起子目录下查找一个包含“CHAT_MESS”的文件,于是,他输入以下命令


find -name "*.*" | grep "CHAT_MESS"


首先分析一下这条语句,find是查找命令,

1. 只要加上-name文件名选项系列(例如-path,-regex等)即可实现递归查找;
2. -name代表查找名字,支持通配符,不支持正则表达式.所以*代表任意长的任意字符,"*.*"代表包含点符号的所有字符
3. 查找到的文件通过管道符传递给grep
4. grep通过模式"CHAT_MESS"查找文件


但,结果什么都没输入.起初我怀疑是管道传输的问题,我用了grep取反命令,

find -name "*.*" | grep -v "CHAT_MESS"


但正确输出结果,后来突然想起来,可以是grep把find的查询结果当作一个文件来对待,查看了man文档,果真如此!man文档如此写着


"grep searches the named input FILEs (or standard input if no files are named, 
or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN. "

原来,如果grep后面没有添加文件,它就把查找标准输入的内容。此时管道重定向了标准输入,所以,它把find的结果当作一个文件来查找,并没有进入find的结果的内部。后来,我把结果改成了

find -name "*.*" | while read arg;do grep "CHAR_MESS" $arg;done

麟则把他改成了

find -name "*.*" -exec find {} \;

两者都能得到结果,但是,结果稍微有些意外。这属于其他内容的问题,上述问题已经解决

关于结果(grep查询结果现实规则)
我们得到的结果是
./.makefile.swp binary file matches
#define CHAR_MESS
这句话让我们误解,以为是#define CHAR_MESS是存放在.makefile.swp中。后来,终于发现,原来,由于.makefile.swp是二进制文件,虽然cat能查看,grep也能进入查看,但是,对于二进制文件,grep只提示在这个文件里边找到了,不提示也无法提示在哪一行。而对于文本文件,由于只有一个匹配,grep默认只有一个匹配是不显示文件的名字,所以它只现实#defind CHAR_MESS。这样对于不了解的人而言很容易误解,所以,可以添加-H参数,让它现实文件名。或者用-l让它现实文件列表。

你可能感兴趣的:(linux,shell)