Linux 系统 grep 命令的使用手册

370 阅读13分钟

系统版本

[root@product ~]# cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core) 

1. 简介

grep命令用于查找文件里符合条件的字符串。

grep指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep指令会把含有范本样式的那一行显示出来。若不指定任何文件名称,或是所给予的文件名为"-",则grep指令会从标准输入设备读取数据。

grep在指定的输入文件中搜索包含与给定模式匹配的内容的行。默认情况下,grep打印匹配的行。另外,有两种不同的程序egrepfgrep可用。egrepgrep -E是一样的,fgrepgrep -F相同。不赞成直接调用egrepfgrep,但是系统会对以前使用它们的应用程序进行兼容处理。

范本样式指要搜索的目标字符串或者目标正则表达式。

2. 语法

grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

3. 参数

通用程序信息

简写全称描述
--help打印一条使用消息,简要总结这些命令行选项和错误报告地址,然后退出。
-V--version将 grep 的版本号打印到标准输出流。这个版本号应该包含在所有 bug 报告中

匹配器的选择

简写全称描述
-E--extended-regexp将 PATTERN 解释为一个扩展的正则表达式。
-F--fixed-strings
--fixed-regexp
将 PATTERN 解释为一个由换行符分隔的固定字符串列表,其中任何一个都要被匹配。
--fixed-regexp 是一个废弃的别名,请不要在新的脚本中使用它)
-G--basic-regexp将 PATTERN 解释为一个基本的正则表达式。这是默认值。
-P--perl-regexp将 PATTERN 解释为一个Perl 的正则表达式。这是一个实验性的参数,系统可能会提示未实现该特性。

匹配控制

简写全称描述
-e PATTERN--regexp=PATTERN使用 PATTERN 作为匹配模式,这可用于指定多个搜索模式,或用字符(-)提供的一个模式。
-f FILE--file=FILE从 FILE 中获取匹配模式,每行一个。空文件包含零模式,因此不匹配任何内容。
-i--ignore-case忽略 PATTERN 和 FILE 中的大小写区别。
-v--invert-match反转匹配的意义,选择不匹配的行。
-w--word-regexp只选择那些包含构成整个单词的匹配项的行。
-x--line-regexp只选择与整行完全匹配的那些匹配项。
-y-i 的同义词,已废弃。

控制输出内容

简写全称描述
-c--count抑制正常输出;相反,为每个输入文件打印匹配行的计数。使用 -v 反向匹配选项,计数不匹配的行。(-c 由 POSIX 指定。)
--color[=WHEN]--colour[=WHEN]将匹配(非空)字符串、匹配行、上下文行、文件名、行号、字节偏移量、和分隔符(用于字段和上下文行组)带有转义序列,以便在终端上以彩色显示它们。颜色由环境变量 GREP_COLORS 定义。已弃用的环境变量 GREP_COLOR 仍然支持,但使用其设置没有优先权。WHEN 的值可以为 never、always、auto。
-L--files-without-match抑制正常输出;相反,列出文件内容不符合指定的范本样式的文件名称。
-l--files-with-matches抑制正常输出;相反,列出文件内容符合指定的范本样式的文件名称。
-m NUM--max-count=NUMStop reading a file after NUM matching lines. If the input is standard input from a regular file, and NUM matching lines are output, grep ensures that the standard input is positioned to just after the last matching line before exiting, regardless of the presence of trailing context lines. This enables a calling process to resume a search. When grep stops after NUM matching lines, it outputs any trailing context lines. When the -c or --count option is also used, grep does not output a count greater than NUM. When the -v or --invert-match option is also used, grep stops after outputting NUM non-matching lines.
-o--only-matching只打印匹配行的匹配部分(非空),每个匹配部分在单独的输出行上。
-q--quiet
--silent
不要写任何东西到标准输出。如果发现任何匹配,立即退出,状态为零,即使出现错误被检测到。也可以查看 -s 选项。
-s--no-messages不显示错误信息。

控制输出行的前缀

简写全称描述
-b--byte-offset输出含有匹配部分的整行内容,打印该行第一个匹配部分基于0位置的字节偏移量。如果指定了 -o (--only-matching) 选项,则只输出匹配部分的内容,每个匹配部分输出为一行,并且在每个匹配部分之前打印出该匹配部分基于0位置的字节偏移量。
-H--with-filename输出含有匹配部分的整行内容,打印该行内容所属的文件名。当有多个文件要搜索时,这是默认值。
-h--no-filename输出含有匹配部分的整行内容,不打印该行内容所属的文件名。当只有一个文件(或只有标准输入)需要搜索时,这是默认值。
--label=LABELDisplay input actually coming from standard input as input coming from file LABEL. This is especially useful when implementing tools like zgrep, e.g., gzip -cd foo.gz, grep --label=foo -H something. See also the -H option.
-n--line-number输出含有匹配部分的整行内容,在输出的每一行前面加上该行的行号。行号在目标文件中是以1为基础的。
-T--initial-tabMake sure that the first character of actual line content lies on a tab stop, so that the alignment of tabs looks normal. This is useful with options that prefix their output to the actual content: -H,-n, and -b. In order to improve the probability that lines from a single file will all start at the same column, this also causes the line number and byte offset (if present) to be printed in a minimum size field width.
-u--unix-byte-offsetsReport Unix-style byte offsets. This switch causes grep to report byte offsets as if the file were a Unix-style text file, i.e., with CR characters stripped off. This will produce results identical to running grep on a Unix machine. This option has no effect unless -b option is also used; it has no effect on platforms other than MS-DOS and MS-Windows.
-Z--nullOutput a zero byte (the ASCII NUL character) instead of the character that normally follows a file name. For example, grep -lZ outputs a zero byte after each file name instead of the usual newline. This option makes the output unambiguous, even in the presence of file names containing unusual characters like newlines. This option can be used with commands like find -print0, perl -0, sort -z, and xargs -0 to process arbitrary file names, even those that contain newline characters.

控制输出行的上下文

简写全称描述
-A NUM--after-context=NUM在打印匹配行之后打印后续上下文的行数。在相邻匹配组之间放置包含组分隔符的行(--group-separator)。和 -o 或者 --only-matching 选项一起使用,没有影响但是会有一个警告。
-B NUM--before-context=NUM在打印匹配行之前打印前导上下文的行数。在相邻匹配组之间放置包含组分隔符的行(--group-separator)。和 -o 或者 --only-matching 选项一起使用,没有影响但是会有一个警告。
-C NUM--context=NUM在打印匹配行前后分被打印上下文的行数。在相邻匹配组之间放置包含组分隔符的行(--group-separator)。和 -o 或者 --only-matching 选项一起使用,没有影响但是会有一个警告。
-NUM--context=NUM同 -C NUM。
--group-separator=SEP使用 SEP 作为分组分隔符。默认情况下 SEP 是双连字符(--)。
--no-group-separator使用空字符串作为组分隔符。

文件和目录的选择

简写全称描述
-a--text像处理文本一样处理二进制文件;相当于 --binary-files=text 选项。
--binary-files=TYPEIf the first few bytes of a file indicate that the file contains binary data, assume that the file is of type TYPE. By default, TYPE is binary, and grep normally outputs either a one-line message saying that a binary file matches, or no message if there is no match. If TYPE is without-match, grep assumes that a binary file does not match; this is equivalent to the -I option. If TYPE is text, grep processes a binary file as if it were text; this is equivalent to the -a option. Warning: grep --binary-files=text might output binary garbage, which can have nasty side effects if the output is a terminal and if the terminal driver interprets some of it as commands.
-D ACTION--devices=ACTIONIf an input file is a device, FIFO or socket, use ACTION to process it. By default, ACTION is read, which means that devices are read just as if they were ordinary files. If ACTION is skip, devices are silently skipped.
-d ACTION--directories=ACTION如果要搜索的是一个目录,使用 ACTION 来处理它。默认情况下,ACTION 是 read(读取),也就是说,读取目录就像读取普通的文件一样。如果 ACTION 是 skip(跳过),会直接跳过目录。如果 ACTION 是 recurse(递归),递归地读取每个目录下的所有文件,仅当符号链接在命令行上时才跟踪它们,这相当于 -r 选项。
--exclude=GLOBSkip files whose base name matches GLOB (using wildcard matching). A file-name glob can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.
--exclude-from=FILESkip files whose base name matches any of the file-name globs read from FILE (using wildcard matching as described under --exclude).
--exclude-dir=DIR从递归搜索中排除与模式 DIR 匹配的目录。
-I处理二进制文件,就好像它不包含匹配的数据一样。它等价于 --binary-files=without-match 选项。
--include=GLOBSearch only files whose base name matches GLOB (using wildcard matching as described under --exclude).
-r--recursive递归地读取每个目录下的所有文件,仅当符号链接在命令行上时才跟踪它们,相当于 -d recurse 选项。
-R--dereference-recursive递归地读取每个目录下的所有文件。遵循所有符号链接,不像 -r。

其他选项

简写全称描述
--line-buffered对输出使用行缓冲。这可能会导致性能损失。
-U--binaryTreat the file(s) as binary. By default, under MS-DOS and MS-Windows, grep guesses the file type by looking at the contents of the first 32KB read from the file. If grep decides the file is a text file, it strips the CR characters from the original file contents (to make regular expressions with ^ and $ work correctly). Specifying -U overrules this guesswork, causing all files to be read and passed to the matching mechanism verbatim; if the file is a text file with CR/LF pairs at the end of each line, this will cause some regular expressions to fail. This option has no effect on platforms other than MS-DOS and MS-Windows.
-z--null-dataTreat the input as a set of lines, each terminated by a zero byte (the ASCII NUL character) instead of a newline. Like the -Z or --null option, this option can be used with commands like sort -z to process arbitrary file names.

4. 示例

4.1. 一般性使用

下面这种格式的就能满足一般性使用,目标字符串不用引号也可以。

grep [参数] [--color=auto] '目标字符串' 文件名

-a 将二进制文件以 text 文件的方式查找数据。 -c 计算找到'目标字符串'的次数。 -i 忽略'目标字符串'大小写的不同。 -n 输出的时候显示行号。 -v 反向选择,显示出没有目标字符串的行。 --color=auto 可以将找到的关键字部分加上颜色显示。 -A 后面加数字N,除了列出目标字符串所在的行外,后续的N行也会列出来。 -B 后面加数字N,除了列出目标字符串所在的行外,前面的N行也会列出来。 -C 后面加数字N,除了列出目标字符串所在的行外,前面的N行和后续的N行都会列出来。

(1)计算/etc/passwd文件中字符串root出现的次数。

grep -c 'root' /etc/passwd

(2)该命令可以使用管道进行连接,比如将/etc/passwd文件中没有出现root字符串并且没有出现nologin字符串的行取出来。

grep -v 'root' /etc/passwd | grep -v 'nologin'

(3)将出现ftp字符串或者root字符串的行显示出来,并显示该行的行号。

grep -n 'ftp' /etc/passwd & grep -n 'root' /etc/passwd

(4)将/etc/passwd文件中出现ftp字符串的行以及该行前面的2行和后续的2行都列出来。

grep -C 2 'ftp' /etc/passwd

4.2. grep 查找的内容输出到文件

使用 grep 查看服务日志是必备的技能,有时候遇上比较难排查的疑难杂症,需要将日志筛选后保存到指定文件,再下载到本地进行日志分析。

将 grep 查找的内容输出到文件的示例:

在文件 server.log 中查找 ‘search-string’ 并输出到用户目录下的/log/test.log文件中:

grep 'search-string' server.log > ~/log/test.log

如果test.log已存在,输出的内容将会覆盖test.log文件原有的内容。

如果test.log不存在,则会创建test.log文件并输出查找到的内容。

若想实现输出的日志只执行追加操作而不覆盖原有的内容,可以使用 >> 代替 > 即可,如下:

grep 'search-string' server.log >> ~/log/test.log

同样的原理,tail、head 等命令输出的内容也可以使用这样的方式输出到文件中。

4.3. grep 过滤多个字符串

grep 是一个强大的命令行工具,用于在文件中搜索特定的字符串或模式。有时你可能需要同时过滤多个字符串。grep 提供了几种方法来实现这一点:

方法一:使用多次 grep

你可以通过管道(|)将多个 grep 命令串联起来,每次过滤一个字符串。例如,假设你想在文件 example.txt 中同时过滤包含 "foo" 和 "bar" 的行:

grep "foo" example.txt | grep "bar"

这个命令首先过滤出包含 "foo" 的行,然后在这些行中进一步过滤出包含 "bar" 的行。

方法二:使用正则表达式 OR 运算符

grep 支持使用正则表达式,因此你可以使用 \|(OR 运算符)来匹配多个字符串。需要注意的是,这里需要使用扩展正则表达式(-E 选项)或兼容 \| 的基本正则表达式。

grep "foo\|bar" example.txt

请确保在过滤多个字符串时使用 \| 将它们组合在一起,反斜杠 \ 用来转义特殊字符。另外,还可以使用 -E 选项来启用扩展的正则表达式语法,这样就不需要转义 | 字符了

grep -E "foo|bar" example.txt

这个命令会匹配包含 "foo" 或 "bar" 的行。如果你想匹配同时包含 "foo" 和 "bar" 的行,仍然需要使用方法一。

方法三:使用 egrep

egrep 是 grep -E 的别名,可以直接使用扩展正则表达式。因此,以下命令与方法二等价:

egrep "foo|bar" example.txt

方法四:使用 awk

awk 是一个更强大的文本处理工具,也可以用来过滤多个字符串。以下是一个示例:

awk '/foo/ && /bar/' example.txt

这个命令会输出同时包含 "foo" 和 "bar" 的行。

方法五:使用 sed

sed 是另一个强大的文本处理工具,虽然它主要用于替换文本,但也可以用来过滤行:

sed -n '/foo/{/bar/p}' example.txt

这个命令的意思是:对于包含 "foo" 的行,进一步检查是否包含 "bar",如果包含则输出。

总结

  • ‌串联 grep‌:适用于需要逐步过滤多个条件的情况。
  • ‌正则表达式 OR‌:适用于匹配任意一个条件的情况。
  • ‌awk‌ 和 ‌sed‌:适用于更复杂的文本处理任务。

选择哪种方法取决于你的具体需求和偏好。