站内链接:

文件相关:

Introduction

文本三剑客

在讲解 grep 命令之前, 先让我们简单的了解一下何为文本三剑客: grep, awk, sed.

  • grep: 基于正则表达式查找到满足条件的行信息, 专注于: 数据查找定位
  • awk: 对定位到的数据行进行切片分段处理, 按列来处理数据, 专注于: 数据切片
  • sed: 对定位到的数据行进行更改, 专注于: 数据修改

grep

搜索输入的 FILES 中每一行是否 match 匹配项, 如果匹配, 提取出来.

  • egrep: 等价于 grep -E
  • fgrep: 等价于 grep -F
  • rgrep: 等价于 grep -R

另外, 对于持续输出数据continuous stream, grep 需要添加--line-buffered(行缓存)才能进行过滤处理.

Format

命令

  1. grep 通用的命令格式如下:
1
2
3
4
5
6
# 正常格式
grep OPTIONS [pattern] [file...]
# 使用正则
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
# 使用egrep, fgrep
grep [OPTIONS] [-E PATTERN | -F FILE] [FILE...]
  1. 各个 options 用法说明:
1
2
3
4
5
6
7
8
grep -i pattern file1       # 忽略大小写
grep -v pattern file2 # 不显示匹配的行, 经常用于管道之后, 见下面的例子
grep -o p f # 匹配的内容以独立的行显示
grep -e p -e p2 f # 使用多个正则
grep -E p f # 使用扩展正则表达式
grep -A -B -C p f # 打印命中数据的上下文, -A 10: 后 10 行, -B 20: 前 20 行
grep pattern -r dir # 递归搜索
grep -n p f # 显示行号

其中-nir常常会一起连用, 表示递归搜索, 忽略大小写, 并打印行号信息

正则

POSIX 正则分为两大流派: BRE(基本表达式), ERE(扩展正则), 其中 grep, vi, sed, 一些数据库都是属于 BRE, 他们是最早的正则表达式, 其元字符必须经过转义才具有特有含义. 当然, egrep, awk 使用的 ERE 功能更加丰富, 而且元字符不需要转义.

  1. BRE
1
2
3
4
5
6
7
8
9
10
11
.						任意单个字符
* 前面的字符或者pattern任意多次
\{m\} 前面的字符或者模式重复m次
\{m, n\} 前面的字符或模式重复m到n次
\{m, \} 前面的字符或模式重复m次及以上
\(regex\) 分组, 配合前面的量词(*, \{m, n\})使用; 向后引用, 分组引用

^ 放在正则表达式开头则匹配行首, 其他位置表示字符本身
$ 放在正则表达式末尾则匹配行尾, 其他位置表示字符本身
[list] 自定义字符集
[^list] 匹配未出现在自定义字符集的字符

例子:

1
2
3
4
5
6
# 1. 匹配abb
ab\{2\}
# 2. 匹配abab
\(ab\)\{2\}
# 3. 向后引用, 匹配: abab, abbbbabbb
\(ab*\)\1
  1. ERE: 所有元字符不需要转义, 另外增加了?, +, |语法, 另外 BRE 和 ERE 都没有贪婪/非贪婪匹配的说法.
1
2
3
4
5
6
7
{m}
{m,n}
(regex)

非贪婪匹配: ?
一个或者多个: +
或关系: |
  1. POSIX 字符集: 不支持其他正则表达式中的\d, \w等符号, 但是定义了一些常用的字符集
1
2
3
4
5
6
7
8
9
10
[:alnum:]				# 数字字母
[:alpha:] # 字母
[:ascii:] # ascii
[:blank:] # 空格和tab
[:cntrl:] # 控制字符
[:digit:] # 数字
[:lower:] # 小写字母
[:upper:] # 大写
[:word:] # 单词
[:xdigit:] # 16进制

Example

  1. 基于管道过滤查找进程或者搭配使用
1
2
3
4
5
6
7
8
9
10
11
12
# 1. 多模式匹配, 在输出ps的同时输出头部信息
ps -l -p $(pgrep -d, gunicorn)
ps -lC gunicorn

# 2. 过滤并忽略某些输出
ps -ef|grep vim | grep -v grep

# 3. 查找并替换
grep -rl 'string1' ./ | xargs sed -i 's/string1/string2/g'

# 4. 对结果排序
grep string filename | sort
  1. 查找目录下所有文件是否包含特定
1
2
# 1. 是否包含特定字符
grep -F "name" . -nir
  1. 其他
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 获取nginx访问日志中 404, 500错误日志的前 3 条
grep -E "500|404" access.log|head -3
# 2. 获取一个页面上的所有http, https链接行
curl https://testerhome.com/ | grep -iE "http|https"

# 3. 使用多个模式, 构成: 或关系
grep -e "Status Code" -e "name" t.txt

# 4. 使用正则(BRE, ERE)
grep "Class [123]" students.txt
grep "1$" students.txt
grep -E "Class [1-3]|Name" students.txt

# 5. 获取 IP 地址
grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" test

# 对find结果进行字符串查找操作
grep -i "mailx" `find /home/ -type f -a -name "*.txt" -exec grep -l "hello world" {} \;`
  1. 获取匹配的前后 N 行, 在异常日志中非常有用
1
grep -10 "patttern" filename

引用