4.2. grep 用例

4.2.1. 什么是 grep?

grep 在输入文件中搜索匹配给定模式列表的行。当它在某行中找到匹配项时,它会将该行复制到标准输出(默认情况下),或者您使用选项请求的任何其他类型的输出。

虽然 grep 期望对文本进行匹配,但它对输入行长度没有限制,除了可用内存外,并且它可以匹配行内的任意字符。如果输入文件的最后一个字节不是换行符grep 会静默地提供一个。由于换行符也是模式列表的分隔符,因此无法在文本中匹配换行符。

一些例子

cathy ~> grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

cathy ~> grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
12:operator:x:11:0:operator:/root:/sbin/nologin

cathy ~> grep -v bash /etc/passwd | grep -v nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
news:x:9:13:news:/var/spool/news:
mailnull:x:47:47::/var/spool/mqueue:/dev/null
xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false
rpc:x:32:32:Portmapper RPC user:/:/bin/false
nscd:x:28:28:NSCD Daemon:/:/bin/false
named:x:25:25:Named:/var/named:/bin/false
squid:x:23:23::/var/spool/squid:/dev/null
ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false
apache:x:48:48:Apache:/var/www:/bin/false

cathy ~> grep -c false /etc/passwd
7

cathy ~> grep -i ps ~/.bash* | grep -v history
/home/cathy/.bashrc:PS1="\[\033[1;44m\]$USER is in \w\[\033[0m\] "

在第一个命令中,用户 cathy 显示来自/etc/passwd包含字符串 root 的行。

然后她显示包含此搜索字符串的行号。

在第三个命令中,她检查哪些用户没有使用 bash,但是具有 nologin shell 的帐户不会显示。

然后她计算具有/bin/false作为 shell 的帐户数量。

最后一个命令显示她主目录中所有以~/.bash开头的文件中的行,排除包含字符串 history 的匹配项,以便排除来自~/.bash_history的匹配项,其中可能包含相同字符串,无论大小写。请注意,搜索的是字符串 "ps",而不是命令 ps

现在让我们看看我们还可以使用 grep 做什么,使用正则表达式。

4.2.2. Grep 和正则表达式

Note如果您不在 Linux 上
 

我们在这些示例中使用 GNU grep,它支持扩展正则表达式。GNU grep 是 Linux 系统上的默认设置。如果您在专有系统上工作,请使用-V选项检查您正在使用的版本。GNU grep 可以从 http://gnu.org/directory/ 下载。

4.2.2.1. 行和单词锚点

从前面的示例中,我们现在只想显示以字符串 "root" 开头的行

cathy ~> grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash

如果我们想查看哪些帐户根本没有分配 shell,我们搜索以 ":" 结尾的行

cathy ~> grep :$ /etc/passwd
news:x:9:13:news:/var/spool/news:

要检查PATH是否在~/.bashrc中导出,首先选择 "export" 行,然后搜索以字符串 "PATH" 开头的行,以便不显示MANPATH和其他可能的路径

cathy ~> grep export ~/.bashrc | grep '\<PATH'
  export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"

类似地,\> 匹配单词的结尾。

如果您想查找作为单独单词(用空格括起来)的字符串,最好使用-w选项,如本例中,我们正在显示根分区的信息

cathy ~> grep -w / /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1

如果未使用此选项,将显示文件系统表中的所有行。

4.2.2.2. 字符类

方括号表达式是由 "[""]" 括起来的字符列表。它匹配列表中任何单个字符;如果列表的第一个字符是脱字符 "^",则它匹配列表中存在的任何字符。例如,正则表达式 "[0123456789]" 匹配任何单个数字。

在方括号表达式中,范围表达式由连字符分隔的两个字符组成。它使用区域设置的排序规则和字符集,匹配排序在两个字符之间的任何单个字符(包括这两个字符)。例如,在默认的 C 区域设置中,"[a-d]" 等效于 "[abcd]"。许多区域设置按字典顺序对字符进行排序,在这些区域设置中,"[a-d]" 通常不等效于 "[abcd]";例如,它可能等效于 "[aBbCcDd]"。要获得对方括号表达式的传统解释,您可以通过将LC_ALL环境变量设置为值 "C" 来使用 C 区域设置。

最后,某些命名的字符类在方括号表达式中是预定义的。有关这些预定义表达式的更多信息,请参阅 grep 手册页或信息页。

cathy ~> grep [yf] /etc/group
sys:x:3:root,bin,adm
tty:x:5:
mail:x:12:mail,postfix
ftp:x:50:
nobody:x:99:
floppy:x:19:
xfs:x:43:
nfsnobody:x:65534:
postfix:x:89:

在该示例中,显示包含字符 "y""f" 的所有行。

4.2.2.3. 通配符

使用 "." 进行单个字符匹配。如果您想获取以 "c" 开头和以 "h" 结尾的所有五个字符的英语字典单词列表(方便解决纵横字谜)

cathy ~> grep '\<c...h\>' /usr/share/dict/words
catch
clash
cloth
coach
couch
cough
crash
crush

如果您想显示包含字面点字符的行,请使用 grep-F选项。

对于匹配多个字符,请使用星号。此示例从系统字典中选择所有以 "c" 开头和以 "h" 结尾的单词

cathy ~> grep '\<c.*h\>' /usr/share/dict/words
caliph
cash
catch
cheesecloth
cheetah
--output omitted--

如果您想在文件或输出中查找字面星号字符,请使用单引号。在下面的示例中,Cathy 首先尝试在/etc/profile中查找星号字符,而不使用引号,这不会返回任何行。使用引号,会生成输出

cathy ~> grep * /etc/profile

cathy ~> grep '*' /etc/profile
for i in /etc/profile.d/*.sh ; do