在讲解管道符之前,先讲解一下行提取命令grep。grep命令的作用是在文件中提取和匹配符合条件的字符串所在的行。命令格式如下:
举一个例子:
因为grep是行提取命令,所以只要一行数据中包含“搜索内容”,就会列出整行的数据。在这个例子中,会在/etc/passwd文件中查找所有包含“/bin/bash”的行。而已知只有可登录用户的Shell才是“/bin/bash”,而伪用户的Shell是“/sbin/nologin”,所以这条命令会列出在当前系统中所有可以登录的用户。
再举几个例子:
find也是搜索命令,那么,find命令和grep命令有什么区别呢?
1)find命令
find命令用于在系统中搜索符合条件的文件名。如果需要模糊查找,则使用通配符(参见2.3.8节)进行匹配。在搜索时,文件名是完全匹配的。完全匹配是什么意思呢?举一个例子:
完全匹配的意思就是:搜索的内容必须和原始文件一模一样,才能被搜索到。
如果想要找到abcd文件,则必须依靠通配符,如find . -name "abc*"。
注意: find命令是可以通过-regex选项识别正则表达式规则的。也就是说,find命令可以按照正则表达式规则进行匹配,而正则表达式是模糊匹配的。但是,对于初学者而言,find和grep命令本身就不好理解,所以在这里只按照通配符规则来进行find查找。
2)grep命令
grep命令用于在文件中搜索符合条件的字符串。如果需要模糊查找,则使用正则表达式(参见3.1节)进行匹配。在搜索时,字符串是包含匹配的。
grep命令就和find命令不太一样了,当使用grep命令在文件中查找符合条件的字符串时,只要搜索的内容包含在数据行中,就会列出整行内容。举一个例子:
通过这两个例子,大家就可以知道完全匹配和包含匹配的区别了。
在Bash中,管道符使用“|”表示。管道符也是用来连接多条命令的,如“命令1 | 命令2”。不过,和多命令顺序执行不同的是,用管道符连接的命令,命令1的正确输出作为命令2的操作对象。在这里需要注意,命令1必须有正确输出,而命令2必须可以处理命令1的输出结果;而且命令2只能处理命令1的正确输出,而不能处理错误输出。
举一个例子。我们经常使用ll命令查看文件的长格式,不过,在有些目录中文件众多,如/etc/目录,使用ll命令显示的内容就会非常多,只能看到最后输出的内容,而不能看到前面输出的内容。这时我们马上想到,使用more命令可以分屏显示文件内容。但是,怎么让more命令分屏显示命令的输出呢?笔者想到了一种笨办法,命令如下:
但是,这样操作实在不方便,这时就可以利用管道符了。命令如下:
可以这样理解这条命令:先把“ll -a /etc/”命令的输出保存到某个临时文件中,再用more命令处理这个文件。也就是第一条命令的正确输出是第二条命令的操作对象。
注意: 因为ll命令操作的是文件名,所以在匹配时使用的是通配符。但是,一旦加入管道符,因为在管道符之后的内容相当于操作的是文件内容,所以在匹配时使用的是正则表达式。
关于管道符,再举几个例子: