grep - 文本搜索工具

  • 原创
  • Madman
  • /
  • 2018-04-08 09:20
  • /
  • 0
  • 381 次阅读

grep - 文本搜索工具-min.png

Synopsis: g/re/p (Globally search a Regular Expression and Print)是类Unix系统中一个强大的文本搜索工具,在给出文件列表或标准输入后,grep会逐行搜索,判断是否与指定的一个或多个正则表达式匹配,并只输出匹配(或者不匹配)的行或文本。grep使用基本正则表达式,egrep支持使用扩展正则表达式,灵活使用正则,配合grep可以实现文件内非常强大的文本搜索功能

1. 常用选项

grep的基本语法为grep [OPTIONS] PATTERN [FILE...],其中PATTERN是匹配的模式,需要说明的是grep支持使用基本正则表达式(BRE),egrep支持使用扩展正则表达式(ERE),而fgrep不支持正则,它搜索字符串而不是搜索匹配表达式的模式

1.1 -i, --ignore-case

忽略字符大小写

# grep 'NTP' /etc/passwd
没有结果

# grep -i 'NTP' /etc/passwd
ntp:x:38:38::/etc/ntp:/sbin/nologin

1.2 -v, --invert-match

反向匹配,即显示没有 '查找字符串' 的所有行

# grep -v '/sbin/nologin' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

1.3 -c, --count

打印每个输入文件中包含匹配模式的行数

# grep -c 'nologin' /etc/passwd
23

或者:
# grep 'nologin' /etc/passwd | wc -l
23

1.4 -n, --line-number

打印匹配到的文本所在行号

# grep -E -n 'sshd|ntp' /etc/passwd
25:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
26:ntp:x:38:38::/etc/ntp:/sbin/nologin

1.5 -l, --files-with-matches

当匹配到的结果非常多时,可以使用-l只显示文件名

# find / -type f 2> /dev/null | xargs -n 10 grep -l '\*'
/boot/grub/splash.xpm.gz
/boot/grub2/i386-pc/acpi.mod
/boot/grub2/i386-pc/date.mod
... ...

1.6 -q, --quiet, --silent

静默模式,不输出任何信息,常用于脚本中条件测试,不需要输出的信息,如果匹配到则命令执行后的返回状态值为 0 ,否则为 1

# grep -q 'sshd\|ntp' /etc/passwd
# echo $?
0

# grep -q 'sshd|ntp' /etc/passwd
# echo $?
1

1.7 -r, --recursive

递归搜索

# grep -r -n 'sshd' /etc
... ...
/etc/group-:44:sshd:x:74:
/etc/gshadow-:44:sshd:!::
/etc/group:44:sshd:x:74:
/etc/gshadow:44:sshd:!::
/etc/passwd-:25:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
/etc/shadow-:25:sshd:!!:16955::::::
/etc/passwd:25:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
/etc/shadow:25:sshd:!!:16955::::::
... ...

1.8 -A NUM, --after-context=NUM

输出匹配行的后 NUM 行

# grep -A2 -n 'sshd' /etc/passwd
25:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
26-ntp:x:38:38::/etc/ntp:/sbin/nologin
27-tcpdump:x:72:72::/:/sbin/nologin

1.9 -B NUM, --before-context=NUM

输出匹配行的前 NUM 行

# grep -B2 -n 'sshd' /etc/passwd
23-postfix:x:89:89::/var/spool/postfix:/sbin/nologin
24-chrony:x:995:993::/var/lib/chrony:/sbin/nologin
25:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

1.10 -C NUM, -NUM, --context=NUM

输出匹配行的前后 NUM 行

# grep -C2 -n 'sshd' /etc/passwd
23-postfix:x:89:89::/var/spool/postfix:/sbin/nologin
24-chrony:x:995:993::/var/lib/chrony:/sbin/nologin
25:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
26-ntp:x:38:38::/etc/ntp:/sbin/nologin
27-tcpdump:x:72:72::/:/sbin/nologin

1.11 --color=auto

匹配文本着色,CentOS7默认设置了alias,其它系统使用# grep --color=auto "match_pattern" file_name

1.12 -E, --extended-regexp

支持使用扩展正则表达式,相当于egrep

1. 基本正则表达式中 { } + | 等元字符需要转义
# head -n 3 /etc/passwd | grep 'o'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
# head -n 3 /etc/passwd | grep 'o{2}'
# head -n 3 /etc/passwd | grep 'o\{2\}'
root:x:0:0:root:/root:/bin/bash

2. 如果指定 -E 选项,扩展正则表达式中 { } + | 等元字符不需要转义
# head -n 3 /etc/passwd | grep -E 'o{2}'
root:x:0:0:root:/root:/bin/bash

1.13 -e PATTERN, --regexp=PATTERN

同时匹配多个模式

# grep -e 'sshd' -e 'ntp' /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
或者:
# grep 'sshd\|ntp' /etc/passwd
# egrep 'sshd|ntp' /etc/passwd

1.14-F, --fixed-strings, --fixed-regexp

支持使用固定字符串,不支持正则表达式,相当于fgrep

1.15 -f FILE, --file=FILE

使用grep script,每行文本包含一个pattern

# cat grep.txt 
sshd
ntp

# grep -f grep.txt /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin

2. 基本正则表达式

参考: Linux/Unix工具与正则表达式的POSIX规范Regex

GNU BRE(Basic Regular Expression),( ) { }需要转义。

原生BRE不支持量词 +?,不支持多选结构 |,不支持反向引用 \1 \2 等;GNU对BRE做了扩展,所以支持前述元字符,但需要转义

而Linux中grep其实是GNU grep,包括后续要介绍的GNU sed都是使用GNU BRE

2.1 元字符

下面示例中的测试文件regular_express.txt请从文章末尾的附件中下载

RE字符 含义与示例
^word 含义:待搜索的字串(word)在行首!
示例:搜索行首为 # 开始的那一行,并显示行号
# grep -n '^#' regular_express.txt
word$ 含义:待搜索的字串(word)在行尾!
示例:搜索行尾为 ! 的那一行,并显示行号
# grep -n '!$' regular_express.txt
. 含义:代表一定有一个任意字符
示例:搜索e.e表示e与e之间一定仅有一个字符(可以是空白符)
# grep -n 'e.e' regular_express.txt
\ 含义:转义字符,将特殊符号的特殊意义去除!
示例:搜索含有单引号'的那一行
# grep -n \' regular_express.txt
* 含义:重复0个到无穷多的前一个RE字符!
示例:ess*表示字符es后面跟0或多个字符s
# grep -n 'ess*' regular_express.txt
[list] 含义:在[ ]当中仅代表一个待查找的字符
示例:查找含有glgd的那一行
# grep -n 'g[ld]' regular_express.txt
[n1-n2] 含义:在[ ]当中-代表两个字符之间所有连续的字符,与ASCII有关,需要正确设置好LANGLANGUAGE
示例:查找所有大写字母
# grep -n '[A-Z]' regular_express.txt
[^list] 含义:在[ ]当中^表示反向选择的意思!
示例:查找oo字符后面跟着的不是t字符的那一行
# grep -n 'oo[^t]' regular_express.txt
\{n,m\} 含义:连续 nm 个的前一个RE字符!
含义:若为 \{n\},则表示连续 n 个前一个RE字符!
含义:若为 \{n, \},则表示连续 n 个以上前一个RE字符!
含义:若为 \{0, n\},则表示最多连续 n 个前一个RE字符!
示例:查找在g与g之间有2个到3个的o存在(即 goog gooog)的那一行
# grep -n 'go\{2,3\}g' regular_express.txt

注意: 不要将正则表达式的元字符与bash的通配符 file globing 搞混淆,例如,通配符 * 表示0或无限多个任意字符,而正则表达式中的 * 表示重复0到无限多个的前一个RE字符

2.2 字符集

使用字符集时,需要用[]包裹下面的集合,例如[[:upper:]]代表一个大写字母

  • [:upper:] 所有大写字母
  • [:lower:] 所有小写字母
  • [:digit:] 所有的数字
  • [:alpha:] 所有字母
  • [:alnum:] 所有字母和数字
  • [:space:] 所有空白字符
  • [:punct:] 所有标点符号

2.3 其它元字符

  • \+ 匹配前面的字符至少一次
  • \? 匹配前面的字符0次或1次
  • .* 代表任意长度的任意字符
  • ^PATTERN$ PATTERN需要完全匹配一整行
  • ^$ 匹配空行
  • ^[[:space:]]*$^$匹配不到时使用,包括空白字符(空格、制表符)
  • \<PATTERN\bPATTERN 词首锚定
  • PATTERN\>PATTERN\b 词尾锚定
  • \<PATTERN\> 单词锚定
  • \(PATTERN\) 分组,将PATTERN匹配到的字符当做一个整体,后续可使用\1引用第一组括号中PATTERN匹配到的字符串, \2引用第二组括号中PATTERN匹配到的字符串...,以此类推
1. 找出 /etc/passwd 文件中的一位数字或两位数字
# grep '\<[0-9][0-9]\?\>' /etc/passwd

2. 查找包含tast或test的行
# grep -n 't[ae]st' regular_express.txt

3. 查找oo前面不是小写字母的行
# grep -n '[^a-z]oo' regular_express.txt
或者
# grep -n '[^[:lower:]]oo' regular_express.txt

4. 去除文本文件中的空白行和以 # 开头的注释行
# grep -v '^$' /etc/ntp.conf | grep -v '^#'
或:
# grep -v -e '^$' -e '^#' /etc/ntp.conf
或:
# egrep -v '^$|^#' /etc/ntp.conf

3. 扩展正则表达式

ERE(Extended Regular Express)中 + ? ( ) { } | 这些元字符不需要转义,| 表示或(or)的意思,()+ 表示一个以上的分组

# egrep -n 'go+d' regular_express.txt
# egrep -n 'go?d' regular_express.txt
# egrep -n 'g(la|oo)d' regular_express.txt
# egrep -n 'gd|good|dog' regular_express.txt
# echo 'AxyzxyzxyzxyzC' | egrep 'A(xyz)+C'
AxyzxyzxyzxyzC
分类: Linux
标签: egrep fgrep grep
附件: regular_express.txt
未经允许不得转载: LIFE & SHARE - 王颜公子 » grep - 文本搜索工具

分享

作者

作者头像

Madman

如果博文内容有误或其它任何问题,欢迎留言评论,我会尽快回复; 或者通过QQ、微信等联系我

0 条评论

暂时还没有评论.

发表评论前请先登录