linux 三剑客 - 文本查找命令 grep
linux 提供了强大的文本分析工具,如 grep
, sed
, awk
,号称三剑客。本篇介绍文本查找命令 grep
。
grep
(global regular expression print)命令能够过滤出文本中符合要求(如正则表达式)的内容、行、文件等。默认在所有 linux 发行版中都预装该命令。
基本命令格式
1 | grep [options|flags] pattern file1 file2 |
如:
1 | # 查找系统上某个用户(如 root)的默认登录 shell |
options
options 有时也叫作 flags,是控制 grep
命令输出内容的参数。下面罗列一些常用的参数,更多请帮助文档:man grep
- –color=always, –color=auto, –color=never: 是否以不同颜色显示查找到的文本内容
- -a, –text:不要忽略二进制数据。用于从二进制文件中查找内容。如果查找二进制文件里的内容,请添加该参数:
grep -a "合并" binary_files
,查找二进制文件中是否包含有 “合并” - -A num, –after-context=num:对于查找到的某一行同时打印该行后 num 行内容,常用于日志分析,如打印报错内容的后面内容:
grep -A 3 "error" run.log
,查找 run.log 中包含有 error 行及其后 3 行 - -B num, –before-context=num:与 -A num 相反,打印某一行的前 num 行:
grep -B 3 "error" run.log
,查找 run.log 中包含有 error 行及其前 3 行 - -C num, –context=num:同时包含 -A num 和 -B num,表示打印找到的某一行的前后各 num 行:
grep -C 3 "error" run.log
,查找 run.log 中包含有 error 行及其前后 3 行 - -c:只打印匹配的行数,不打印查找到的文本内容
- -e pattern, –regexp=pattern:指定字符串作为查找文件内容的范本样式,这里字符串可以是正则表达式(下面介绍),可以指定多个 -e,用于查找多个内容:
grep -e "root" -e "bash$" /etc/passwd
,查找 root,以及以 bash 结尾的行 - -E pattern, –extended-regexp=pattern:扩展正则表达式,即 egrep,指定可以使用扩展的正则表达式(下面介绍),示例:
grep -E "ro+t" /etc/passwd
,查找 root, rooot, … - -i, –ignore-case:忽略字符大小写,如同时查找 h 和 H:
grep -i "h" /etc/passwd
,查找 /etc/passwd 中包含有 h,H 的行 - -l, –file-with-matches: 列出文件内容符合指定的 pattern 的文件名称:
grep -l "root" /etc/*
,查找 /etc 目录下所有包含 root 文本内容的文件名 - -L, –files-without-match: 列出文件内容不符合指定的 pattern 的文件名称:
grep -L "root" /etc/*
,列文件夹 /etc 下不包含文本内容 root 的所有文件名 - -n, –line-number: 打印找到的那一行内容前增加上行号:
grep -n "root" /etc/passwd
- -q, –quiet或–silent:不显示任何信息
- -R/-r, –recursive: 递归搜索文件夹里面的文件,与 -d recurse 参数含义相同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 递归搜索 /etc 目录下所有文件包含 root 内容的行
grep -r "root" /etc
# 递归搜索 ./codes 目录下所有以 py,sh,php,html,txt,md 结尾的文件里含有 sam 的行
grep -r --include=*.{py,sh,php,html,txt,md} "sam" ./codes
# 递归搜索 ./codes 目录下所有包含 sam 的文件行,但不包含以 .json 结尾的文件
grep -r --exclude=.json "sam" ./codes
# 递归搜索 ./codes 目录下所有文件包含 sam 的文件行,但是排除文件 filelist 中列出的所有文件
grep -r --exclude-from=filelist "sam" ./codes
# 递归搜索 ./codes 目录下所有文件包含 sam 的文件行,但是排除文件夹 py
# py 可以是 codes 下的文件夹,也可以是其下子文件夹里的文件夹,但只需要指定文件夹名即可,不需要写相对或绝对路径
grep -r --exclude-dir=py "sam" ./codes - -s, –no-messages:不显示错误信息
- -v, –revert-match:反转查找,即对于匹配到的 pattern 不显示,如:
ps ef | grep python | grep -v grep
,查找 python 进程,但是不显示 grep 查找自己的进程 - -V, –version:显示版本信息
- -o:只输出文件中匹配到的部分,不打印行自打印查找到的文本内容本身
- -m
, –max-count= :找到 num 行结果后停止查找,用来限制匹配行数
例子:
1 | # 查找文件中有多少个 sam 文本内容 |
pattern
pattern 可以是文本内容,也可以是正则表达式,或扩展正则表达式。
正则表达式
使用正则表达式:
1 | # 可以指定多个 -e |
符号 | 含义 |
---|---|
^ | 锚定行的开始,如 “^import” 匹配所有以 import 开头的行 |
$ | 锚定行的介绍,如 “p$” 匹配所有以 p 结尾的行 |
^$ | 匹配空白行 |
. | 匹配一个非换行符的字符,如 “impo.t” 可以匹配 import,impoot, … |
* | 匹配零个或多个前一个字符,如 “1*” 匹配 1 后零个或多个 1 |
.* | . 和 * 一起使用可以匹配任意字符 |
[] | 匹配一个指定范围内的字符,如 “[a-z]” 匹配字符 a 到 z 的所有单个小写字符,”[0-9a-zA-Z]” 匹配所有单个数字或字符 |
[^] | 与 [] 相反,匹配一个不在指定范围外的字符,如 “[^0-57-9]” 只匹配数字 6 |
\< | 锚定单词的开始,如 “<np” 或 “\bnp”,匹配某行中独立的以np开头的单词,不一定在行首 |
\> | 锚定单词的结束,如 “np>“ 或 “np\b”,匹配某行中独立的以 np 结尾的单词,不一定在行尾 |
\w | 匹配一个英文字符或数字,同[0-9a-zA-Z] |
\W | 与 \w 相反,匹配除了英文字符和数字外的单个字符 |
\b | 单词锁定,”\bas\b” 或者 “<as>“ 只匹配单词 as |
Linux 系统中默认在每行行尾添加上符号 $,可以通过命令 cat -A file
查看
示例:
1 | # 表示匹配一个数字+b组成的字符对 |
扩展正则表达式
扩展正则表达式(ERE,Extended Regular Expression),在正则表达式的基础上增加上 {}()?+|
1 | grep -E "xxx" file |
符号 | 含义 |
---|---|
+ | 匹配前面的一个字符 1 次或多次 |
? | 匹配其前面的字符 1 次或 0 次,使用 grep “a?b” file, 匹配 b, ab |
x{m} | 重复字符 x 正好 m 次 |
x{m,} | 重复字符 x 至少 m 次 |
x{m,n} | 重复字符 x 至少 m 次,至多 n 次,默认以贪婪匹配,匹配字符尽量多 |
(x) | 标记匹配字符,x 内容被标记为 \1 |
| | | 表示或,如 a|b 表示匹配 a 或者 b |
示例:
1 | # 表示 ab 整体作为匹配字符,且匹配至少一次 |
POSIX字符
为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating System Interface)增加了特殊的字符类,如 [:alnum:] 是 [A-Za-z0-9] 的另一个写法。要把它们放到 [] 号内才能成为正则表达式,如 [A- Za-z0-9] 或 [[:alnum:]]。在 linux 下的 grep 除 fgrep 外,都支持 POSIX 的字符类。
- [:alnum:] # 文字数字字符,表示所有字母和数字 [0-9a-zA-Z]
- [:alpha:] # 文字字符,表示所有字母(包含大小写) [a-zA-Z]
- [:digit:] # 数字字符,所有数字 [0-9]
- [:graph:] # 非空字符(非空格、控制字符)
- [:lower:] # 小写字符,所有小写字母 [a-z]
- [:cntrl:] # 控制字符
- [:print:] # 非空字符(包括空格)
- [:punct:] # 标点符号,所有标点符号
- [:space:] # 所有空白字符(新行,空格,制表符), 表示空格或tab键
- [:upper:] # 大写字符,所有大写字母 [A-Z]
- [:xdigit:] # 十六进制数字(0-9,a-f,A-F)
退出状态
item | description |
---|---|
0 | A match was found |
1 | No match was found |
>1 | A syntax error was found or a file was inaccessible (even if matches were found) |
与其他命令结合
1 | # echo |
参考文献
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 J. Xu!
评论