grep 命令详解
概述:本文档基于 info grep 翻译,完成度可能 90% 左右。
作者:N10-guli
时间:2016-01-05
版本:v1.0
目录:
1,grep 命令的选项
2,grep 命令的正则表达式
3,grep 命令使用示例
1,grep 命令的选项
1.1 概念
grep 从输入的文件中,寻找与 pattern list 匹配的行。 因为换行符也是 pattern list 的分隔符,所以不可能对换行符做匹配。
1.2 调用 grep 的语法
grep OPTIONS.. PATTERN INPUT_FILE_NAMES.. 除了这种写法,pattern 也可以由 -e PATTERN 给出,或者从文件中读取 pattern -f FILE 。 省略号 .. 表示可以有多个
1.3 命令行选项
grep 命令有许多选项,来自 POSIX.2 和 GNU 的扩展。 长选项通常是 GNU 的扩展,短选项由 POSIX 指定。
1.3.1 普通的程序信息
--help 帮助 -V, --version 打印版本号
1.3.2 匹配控制
-e PATTERN, --regexp=PATTERN 可指定多个 PATTERN, 或用于保护以 - 开头的 PATTERN -f FILE, --file=FILE 从 FILE 中获取 PATTERN, 一行为一个。空文件什么都不匹配。 -i, --ignore-case 忽略大小写 -v, --invert-match 找出不匹配的行 -w, --word-regexp 整词匹配,匹配的字符串的前后不能是 字母,数字或下划线。 -x, --line-regexp 整行匹配
1.3.3 总体输出控制
-c, --count 打印每个文件中匹配的行数 --color[=WHEN] grep 结果的颜色控制,WHEN=never, always, auto 颜色由 GREP_COLORS 设置。 -L, --files-without-match 只打印没有匹配行的文件的文件名 -l, --files-with-matches 只打印有匹配行的文件的文件名 -m NUM, --max-count-NUM 匹配到了 NUM 行,就停止。 while grep -m 1 PATTERN do echo xxxx done < FILE 这个脚本的含义是:在 FILE 中每匹配一行,执行一次 echo xxx。 与 -c 配合,输出必然小于等于 NUM 与 -v 配合,输出不匹配的行,最多 NUM 行。 -o, --only-mathing 只打印匹配的部分,而非整行 -q, --quit, --silent 如果有匹配的行,立即结束进程,返回 0 状态值,不输出任何信息。 -s, --no-messages 当遇到不存在的文件,或不可读的文件时,不打印错误。 为了脚本的可移植性,建议重定向标准输出和错误输出。
1.3.4 输出行的前缀控制
打印多个前缀字段时,顺序是固定的:文件名,行序号,字节偏移 以冒号':'分隔。 -b, --byte-offset 打印每一行的字节偏移(0-based)。 带了 -o 选项时,只计算匹配字符串的偏移。 -H, --with-filename 有多个文件输入时,默认带有 -H 选项。 在每一个匹配行之前,打印文件名前缀 -h, --no-filename 单个文件输入时,默认带有 -h 选项。 不打印文件名前缀。 --label=LABEL Display 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 -n, --line-number 打印行序号前缀(1-based) -T, --initial-tab 使用 tab 使行尽可能对齐。 -u, --unix-byte-offsets 配合 -b 使用,使在 MS-DOW, MS-Windows 的输出与 Unix 环境相同 -Z, --null 在文件名后使用 zero byte(ASCII 的 NUL 字符)代替换行符 grep -lZ FILE 输出的文件名以 nul 结尾。 配合 find -print0, sort -z, xargs -0, perl -0, 即使文件名含有特殊字符如 换行符,也能正确处理。
1.3.5 文本行控制
所有输入的行在输出中只会打印一次。相邻的输出有重合时,自动合并。 注意:以下的选项在使用 -o 选项后失效 -A NUM, --after-contex=NUM 打印匹配行以及其后的 NUM 行 -B NUM, --before-contex=NUM 打印匹配行以及其前的 NUM 行 -C NUM, -NUM, --contex=NUM 打印匹配行以及之前,之后的 NUM 行 --group-separator=STRING -A, -B,—C 的输出,以 -- 分隔不同的组 这个选项可设置为以 STRING 分隔 --no-group-separator 不同的组,不做分隔
1.3.6 文件和目录选项
-a, --text 把二进制文件当做文本文件处理,有可能输出垃圾信息,产生边际效应。 (输出的信息被终端解释为其他命令) 等同于 --binary-files=text --binary-files=TYPE 如果文件首部的字节指示这是一个二进制文件,当 TYPE=binary(默认值): 有匹配时,输出一条消息,说明匹配了 无匹配时,没有输出 TYPE=without-match: 假定没有匹配,与 -I 相同 TYPE=text 与 -a 相同,将其当做 文本文件处理 -D ACTION, --devices=ACTION 输入文件为 device, FIFO, socket 时。 使用 ACTION 处理。默认为 read, 正常读取。 如果为 skip, 这类文件被跳过,不做处理。 -d ACTION, --directories=ACTION 输入文件为 目录时,使用 ACTION 处理。 默认为 read, 将目录文件当做普通文件读取。 skip: 跳过 recurse: 目录下的文件都被递归地读取, 同于 -r --exclude=GLOB GLOB 使用通配符匹配文件名:*, ?, [], [^], \ 反斜线可以使通配符变为普通字符。 跳过匹配的文件名,不做处理 --exclude-from=FILE 从文件中读取要跳过的 GLOB --exclude-dir=DIR DIR 为 PATTERN 匹配的 dir 不做递归读取 -I 二进制文件当做不匹配处理 --include=GLOB 只处理 GLOB 匹配的文件。 GLOB 是通配符 -r, -R, --recursive 命令行中的每一个目录,对其中的所有文件读取并处理, 其中还有目录的话,继续做递归处理。
1.3.7 其他选项
--line-bufferd 在输出时使用 line buffering --mmap 读取输入时,使用 mmap 代替 read 函数 -U, --binary 仅在 MS-DOS, MS-Windows 有效。 grep 会通过文件 首部的32KB,猜测文件类型。 如果认为是 文本文件,会除去 CR 字符。 -U 会跳过猜测步骤而直接读取,这样遇到 CR/LF 结尾时可能使匹配出错 -z, --null-data 把输入的行看做以 NUL 结尾的行(正常是以 newline 结尾)进行处理。
1.4 环境变量
grep 的使用受到以下 环境变量 的影响 LC_FOO 类的变量与三个变量的值有关系,依次检查 LC_ALL, LC_FOO, LANG, 以第一个非空的变量值作为 LC_FOO 的值。如果都是空值,或者 locale 目录没有安装, 或者 grep 程序没有在编译时加入 国际语言 支持,这时就使用 C 作为变量值。 GREP_OPTIONS 指定默认选项,选项之间以空格分隔,默认选项放在显式给出的选项之前。 选项含有 \ 或者空格时,使用 \ 反斜线 转义空格和 \, GREP_COLOR 已过时,但仍被支持 指定匹配部分的高亮颜色,默认为 01;31,加粗,红色前景色。 GREP_COLORS 指定输出的高亮颜色。 默认值为(以冒号作为分隔符) ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=36 这部分太长,没有翻译了。 LC_ALL LC_COLLATE LANG 影响 [a-z] 的表示意义。 LC_ALL LC_CTYPE LANG 指定 字符类型。如,哪一个字符表示 空格。 LC_ALL LC_MESSAGES LANG 指定 grep 产生的消息使用的语言 默认为 C 表示使用美国英语。 POSIXLY_CORRECT grep 的行为更符合 POSIX.2 的要求。 默认是 GNU 的风格。 POSIX.2 要求文件名后的 选项,被当做文件名看待,GNU 则将之重新排列,仍视为选项 POSIX.2 要求不能识别的选项被判断为 非法,GNU 则判断为 无效 _N_GNU_nonoption_argv_flags_ (N 为 grep 的进程 ID 号) 如果变量值的第 I 个字符为 1,则 grep 的第 I 个操作数将不被认为是 操作数。 用于防止文件名通配符的展开,被误认为选项。 此行为只在 GNU C library 支持下有效。 POSIXLY_CORRECT 禁用此选项。
1.5 退出状态值
正常情况下,如果有匹配的行,状态返回值为 0, 否则为 1。 有错误发生时,返回 2,除非带有 -q, 或 --quiet, 或 --silent 选项,并且有匹配的行。 Note, however, that POSIX only mandates, for programs such as `grep', `cmp', and `diff', that the exit status in case of error be greater than 1; it is therefore advisable, for the sake of portability, to use logic that tests for this general condition instead of strict equality with 2.
1.6 grep 程序
grep 从输入的文件中(- 或者没有输入文件名时,表示从标准输入中读取) 寻找与 PATTERN 匹配的行。 有四种不同的 grep 程序,由以下选项控制选取。 -G, --basic-regexp 以基本正则的语法解释 pattern。这是默认选项。 -E, --extended-regexp 以扩展正则的语法解释 pattern。 -F, --fixed-strings 将 pattern 视为匹配固定的字符串,不同的 pattern 以 换行符分隔 -P, --perl-regexp 实验中的选项。以 Perl 正则的语法解释 pattern egrep 等同于 grep -E fgrep 等同于 grep -F 这两个命令已经过时,不建议使用。但仍被支持。
2,grep 的正则表达式
正则表达式通过一个 pattern 描述一组字符串。 grep 支持三种正则表达式: 1,基础正则,BRE 2,扩展正则,ERE 3,perl 正则 对于 GNU 的 grep,基础正则与扩展正则的功能没有区别。 在其他的实现中,基础正则的功能一般会弱一些。 以下的描述适用于 扩展正则,其与 基础正则的区别在后面会给出总结。 perl 正则提供更多功能,可参考 pcresyntax(3), pcrepattern(3) 的文档。 可能不适用于每一个系统。
2.1 基本结构
正则表达式基础的部分:单个字符的匹配。 大部分字符在正则表达式中代表其本身。 元字符是有特殊意义的字符,使用反斜线 \,可以使其失去特殊意义,代表其本身。 .匹配任意单个字符 ?此符号前面的字符可出现 0 次 或 1 次 * 此符号前面的字符可出现 0 次 或 多次 +此符号前面的字符可出现 1 次 或 多次 {N} 此符号前面的字符刚好出现 N 次 {N,} 此符号前面的字符出现 N+ 次 {,M} 此符号前面的字符出现 0~M 次 {N,M} 此符号前面的字符出现 N~M 次 两个正则表达式可以进行串联,最终匹配的字符串,由分别匹配两个 正则表达式的字符串连接而成。 两个正则表达式可以进行并联,EXPR | EXPR,表示匹配其中一个 重复的优先级高于串联,这两者的优先级又高于并联。 也可使用(),改变优先级关系,()中的表达式优先做处理。
2.2 字符分类和括号表达式
[LIST] 表示 LIST 字符列表中的任意一个 [^LIST] 表示 LIST 字符列表之外的任意一个 [0123456789] 表示任意一个数字 在默认的 C locale 中,[a-d] = [abcd] 在其他的 locale 中,[a-d] 可能等于 [aBbCcDd] 可设置 LC_ALL 为 C,保证是传统的解释 [a-d]=[abcd]。 以下是一些以名字分类的字符集,其解释依赖于 LC_CTYPE 以下是 LC_CTYPE=C 时的解释 大多数 元字符 在 [] 中失去其特殊含义,变为普通字符。 比较特殊的是 ']', '[]]' 匹配 ']' 字符,']' 必须放在中括号中的第一个位置 [:alnum:] 所有字母(包括大小写字母,下同)和数字 [:alpha:] 所有字母 [:blank:] 空格,制表符 [:digit:] 所有数字 [:graph:] 所有字母,数字,标点符号 [:lower:] 所有小写字母 [:upper:] 所有大写字母 [:print:] 所有字母,数字,标点符号,空格 [:punct:] 所有标点符号: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ [:space:] 制表符,换行符,垂直制表符,跳页, 回车,空格 [:xdigit:] 16进制字符 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
2.3 反斜线和特殊表达式
\b 匹配单词边缘的空字符串 \B 匹配非单词边缘的空字符串 \<匹配词首的空字符串 \>匹配词尾的空字符串 \w与 [[:alnum:]] 同义,匹配一个单词 \W与 [^[:alnum:]] 同义,匹配非单词字符组成的一个单词 \brat\b 匹配独立的单词 rat \Brat\B 匹配 crate,不匹配 furry rat
2.4 锚定
^ 和 $ 是元字符,匹配行首和行尾的空字符串
2.5 反向引用和子表达式
\N,引用第 N 个() 匹配的内容。 (a)\1 匹配 aa 当使用 -e 或 -f 指定多个正则表达式,反向引用的有效范围限定于当前表达式
2.6 基本正则 vs 扩展正则
在基本正则中,?,+,{,},|,(,) 失去了特殊意义 使用:\?, \+, \{, \}, \|, \(, \) 传统的 egrep 不支持 { 元字符,有一些支持 \{ 元字符。 所以,可移植的脚本应该避免在调用 grep -E 时使用 { 元字符。 使用 [{] 可以使其失去特殊意义,匹配 { 字符 GNU grep -E 支持传统的用法,如果 { 没有成对使用 grep -E '{1' 将会匹配 '{1' 字符串,而不是报错。 POSIX.2 允许这种扩展,但是为了可移植性,应避免使用。
3,grep 使用示例
1, 只输出有匹配的文件的文件名 grep -l 'main' *.c 列出含有 main 的 C 文件名 2,如何递归地搜索目录 grep -r 'hello' /home/gigi 进一步限定搜索范围,可以使用 find, xargs 配合 grep: find /home/gigi -name '*.c' -print0 | xargs -r0 grep -H 'hello' 与之类似: grep -rH --include='*.c' 'hello' /home/gigi 下面这条命令与上面的命令不同,它的搜索范围限于当前目录: grep -rH 'hello' *.c 3,如果 pattern 以 - 开头怎么办? grep -e '--cut here --' * 如果这里不加 -e,grep 尝试将 pattern 解释成一组选项 4,假如我想搜索整个单词,而不是单词的一个部分该如何做? grep -w 'hello' * 这条命令不会匹配 Othello,只会匹配单独的单词 hello。 使用 '\<' 和 '\>' 可以分别匹配词首和词尾,比如 grep 'hello\>' * 这会匹配以 hello 结尾的单词,比如 Othello。 (做整词匹配的单词两旁相邻位置不应该有 数字,字母,下划线,这些被定义为单词成分) 5,查看匹配行前面的行和后面的行 grep -C 2 'hello' * 6,在输出行加上文件名前缀 加上 /dev/null grep 'sshd' /etc/passwd /dev/null GNU 中可以使用 -H: grep -H 'sshd' /etc/passwd 7,为什么在过滤 ps 的输出,会有奇怪的正则? ps -ef | grep '[c][/c]ron' 如果不加 [],会输出 grep 进程那一行。 8,为什么 grep 报告 Binary file matches 如果 grep 输出一个二进制文件的匹配行,一般是无用的信息。 所以 grep 默认不输出匹配信息。 强制输出,使用 --binary-files=text 消除 "Binary file matches" 信息,使用: -I 或者 --binary-files=without-match 9,为什么 grep -lv 不打印没有匹配行的文件的文件名? grep -lv 列出含有一个或多个不匹配行的文件名,这个文件中可能还有匹配的行。 列出没有匹配行的文件名,使用: grep -L 或者 grep --files-without-match 10,使用什么表示 and 关系 grep 'paul' /etc/motd | grep 'franc,ois' 调用两次 grep 11,如何同时从 标准输入和文件中读取 使用特殊文件名 - cat /etc/passwd | grep 'alain' - /etc/motd 12,从 ifconfig 输出中抓取 ipv4 地址(添加的例子,仅供参考) ifconfig | grep -E "([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])\.([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])\.([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])\.([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])"
原创文章,作者:guli3057,如若转载,请注明出处:http://www.178linux.com/10903
评论列表(1条)
分类清晰明了