1. 管道
1.1 语法
管道使用竖线“|”作为操作符,管道格式为:
command1 | command2 | command3 ...
说明:系统会先执行command1 ,并将结果交给command2处理,以此类推。
1.2 常见用法
1 .在某个命令的输出中筛选结果
echo "hello1234" | grep "hello"

2.辅助处理结果命令输出。例如:输出本地网络接口卡收发数据详情
netstat -i | sed '1d' | awk '{OFS="\t"}{print $1,$4,$8}'

2. 正则表达式
2.1 定义
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
个人理解就是查找字符用的。
2.2 在线测试工具
2.3 举例
-
找出所有hei单词
hei

hei

\bhei\b

\bhei\b

-
找出hei单词后面有doug的单词
\bhei\b.*\bdoug\b

\bhei\b.*\bdoug\b

\bhei.*doug\b

-
找出010-开头的座机电话
^010-\d{8}

2.4 语法
我们不难看出,上面例子中的正则表达式是由2部分组成:元字符 + 限定符
我的理解:(匹配样式 + 匹配次数) 或 (匹配位置 + 匹配样式 + 匹配次数)
常用元字符 | |
---|---|
代码 | 说明 |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。 |
\w | 匹配字母、数字、下划线。等价于’[A-Za-z0-9_]’ |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 注意 Unicode 正则表达式会匹配全角空格符。 |
\d | 匹配一个数字字符。等价于 [0-9] |
\b | 匹配一个单词的开始位置或结束位置,即字与空格间的位置 |
^ | 匹配输入字符串的开始位置, 除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。 要匹配 ^ 字符本身,请使用 ^。 |
$ | 匹配输入字符串的结尾位置。 如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。 要匹配 $ 字符本身,请使用 \$。 |
备注:\b 、^ 、$ 属于定位符
参考:RUNOOB.COM
常用限定符 | |
---|---|
代码 | 说明 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,} |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 或 “does” 。? 等价于 {0,1} |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
备注:其中“+”,“?”,“{n}”,“{n,}”,“{n,m}”这些属于扩展正则,gerp引用时,需要使用 -E 参数。sed引用时,需要使用 -r 参数
参考:RUNOOB.COM
2.5 练习
-
匹配以字母a开头的单词
\ba\w*\b

备注:^a\w* 这个命令为什么不行?
-
匹配刚好6个字符的单词
\b\w{6}\b

-
匹配1个或更多连续的数字
\b\d+\b

-
5位到12位QQ号
\b[1-9]\d{4,11}\b

3. Linux的查找和筛选工具
3.1 查找文本工具-grep
3.1.1 简介
grep全称global regular expression print(全局正则表达式打印),grep用于查找含有指定的模式(pattern)相匹配的内容的行,并将含有匹配内容的行打印。
备注:模式可简单理解为正则表达式
3.1.2 语法
grep [options] pattern [file...]
3.1.3 常用参数
参数 | 参数全称 | 说明 |
---|---|---|
-n | –line-number | 显示匹配的行号 |
-c | –count | 统计匹配的行数 |
-o | –only-matching | 仅显示匹配到的字符串 |
-i | –ignore-case | 忽略大小写 |
-v | –invert-match | 反转,即显示匹配内容之外的行 |
-E | –extended-regexp | 扩展正则,可使用 and操作,用“|”表示 |
3.1.4 练习1(-n,-v)
新建test.txt文件
root 123
root123
doug 234
root
9999
8888

- 查找文件内容包含root的行数
语法:
grep [options] pattern [file...]
命令:
grep -n root test.txt

- 查找文件内容不包含root的行
语法:
grep [options] pattern [file...]
命令:
grep -nv "root" test.txt

3.1.5 练习2(^,$)
修改test.txt文本,如下
root 123
root123
doug 234
root
aaaaroot
aaa root
aaa root g
9999g
8888

- 查找以r开头的行
语法:
grep pattern [file...]
命令:
grep ^r test.txt

- 查找以g结尾的行
语法:
grep pattern [file...]
命令:
grep g$ test.txt

3.1.6 练习3(-E,-c)
修改test.txt文本,如下
192.168.1.1 2021-02-17 01:00:00 root HTTP
192.168.1.2 2021-02-18 02:00:00 doug HTTP
192.168.1.3 2021-02-18 03:00:00 root HTTP
192.168.1.2 2021-02-18 03:00:00 doug HTTP
192.168.1.4 2021-02-18 04:00:00 doug HTTP
192.168.1.5 2021-02-18 05:00:00 root HTTP
192.168.1.6 2021-02-18 06:00:00 root HTTP
192.168.1.6 2021-02-18 06:10:00 root HTTP
192.168.1.6 2021-02-18 06:20:00 root HTTP
192.168.1.7 2021-02-19 07:00:00 root HTTP

- 查询2021年2月17日 或 2021年2月19日的访问记录
语法:
grep [options] pattern [file...]
命令:
grep -E "2021-02-17|2021-02-19" test.txt

- 查询2021年2月18日 root用户的访问记录
语法:
grep [options] pattern [file...]
命令:
grep "2021-02-18.*root" test.txt
或
grep -E "2021-02-18.*root|root.*2021-02-18" test.txt
或
grep "2021-02-18" test.txt | grep "root"

- 统计2021年2月18日 root用户的访问次数
语法:
grep [options] pattern [file...]
命令:
grep -c "2021-02-18.*root" test.txt
或
grep "2021-02-18" test.txt | grep -c "root"

备注:练习3参考
3.1.7 练习4(+,?,{n},{n,},{n,m})
常用限定符中扩展正则练习
echo "aaaffff" | grep "f+"
echo "aaaffff" | grep -E "f+"
echo "aaaffff" | grep "f?"
echo "aaaffff" | grep -E "f?"
echo "aaaffff" | grep "f{3}"
echo "aaaffff" | grep -E "f{3}"
echo "aaaffff" | grep "f{2,}"
echo "aaaffff" | grep -E "f{2,}"
echo "aaaffff" | grep "f{1,4}"
echo "aaaffff" | grep -E "f{1,4}"

3.2 流编辑器-sed
3.2.1 简介
sed全称 stream editor(流编辑器),sed对文本进行编辑,再输出编辑结果。
原理:
1. 读取文本中的第一行,并将其放入临时缓冲区中,称为“模式空间”(pattern space)
2. sed命令处理缓冲区的内容(使用指令中的模式和行号查找、编辑文本)
3. 处理完后,输出,读取下一行。不断重复,直到文件末尾
备注:
mac系统请使用gsed
3.2.2 语法
sed [option] [-e script] [-f script][input-file]
3.2.3 常用参数
参数 | 参数全称 | 说明 |
---|---|---|
-e | –expression | 指定script(正则)处理(过滤)文本。 只有一条script时,可以省略。多条时,使用该指令逐一添加。 |
-i | –in-place | 编辑原文件 |
-f | –file | 指定含有编辑指令的脚本文件 |
-n | –quiet | 不输出所有行(即,输出匹配到的行) |
-r | –regexp-extended | 使用扩展正则表达式,例如:“|” |
参考:Linux sed 命令 和 man sed
3.2.4 常用定位方式
参数 | 说明 |
---|---|
n | 表示行号为n的行 |
m,n | 表示一个行号范围,从第m行到第n行 |
/pattern/ | 表示匹配pattern的所有行 |
/pattern1/pattern2/ | 表示匹配pattern1和pattern2的所有行(需要使用参数将两个模式隔开) |
参考:《Linux命令、编辑器与Shell编程》/王刚
3.2.5 常用动作
参数 | 说明 | 举例 | 说明 |
---|---|---|---|
p | 打印; | sed -n ‘/root/p’ | 打印包含root字符的行 /pattern/表示正则 |
a | 新增(追加);在指定行后面加入 | sed -e '4a newline’ 或 sed -e ‘4 a newline’ | 在第4行后面添加newline |
i | 插入;在指定行前面加入 | sed -e '2i newline’ 或 sed -e ‘2 i newline’ | 在第2行前面添加newline |
c | 替换;串取代n1,n2之间的行 | sed -e ‘2,5c No 2-5 number’ | 用No 2-5 number取代 2到5行的内容 |
s | 替换;用正则与模式空间匹配,如果匹配,则替换 | sed -e ‘s/old/new/g’ | 使用new替代old;g代表替换当前行所有old |
d | 删除;删除指定行 | sed -e ‘2,5d’ | 删除2到5行 |
参考:霍格沃兹测试学院
3.2.6 练习1-查询(-n,p,-r)
修改test.txt文本,如下
192.168.1.1 2021-02-17 01:00:00 root HTTP
192.168.1.2 2021-02-18 02:00:00 doug HTTP
192.168.1.3 2021-02-18 03:00:00 root HTTP
192.168.1.2 2021-02-18 03:00:00 doug HTTP
192.168.1.4 2021-02-18 04:00:00 doug HTTP
192.168.1.5 2021-02-18 05:00:00 root HTTP
192.168.1.6 2021-02-18 06:00:00 root HTTP
192.168.1.6 2021-02-18 06:10:00 root HTTP
192.168.1.6 2021-02-18 06:20:00 root HTTP
192.168.1.7 2021-02-19 07:00:00 root HTTP

- 查询第3行
语法:
sed [option] [-e script] [input-file]
命令:
sed -n '3p' test.txt

- 查询第3行至第5行
sed -n '3,5p' test.txt

- 查询2021年2月17日 或 2021年2月19日的访问记录
sed -nr '/2021-02-17|2021-02-19/p' test.txt
或
sed -nE '/2021-02-17|2021-02-19/p' test.txt

备注:使用“|” 符号需要加r。不知道为什么E也可以
- 查询2021年2月18日 root用户的访问记录
sed -n '/2021-02-18.*root/p' test.txt
或
sed -n '/2021-02-18/p' test.txt | sed -n '/root/p'

3.2.7 练习2-插入(a,i)
修改test.txt文本,如下
192.168.1.1 2021-02-17 01:00:00 root HTTP
192.168.1.2 2021-02-18 02:00:00 doug HTTP
192.168.1.3 2021-02-18 03:00:00 root HTTP
192.168.1.2 2021-02-18 03:00:00 doug HTTP
192.168.1.4 2021-02-18 04:00:00 doug HTTP
192.168.1.5 2021-02-18 05:00:00 root HTTP
192.168.1.6 2021-02-18 06:00:00 root HTTP
192.168.1.6 2021-02-18 06:10:00 root HTTP
192.168.1.6 2021-02-18 06:20:00 root HTTP
192.168.1.7 2021-02-19 07:00:00 root HTTP

- 在第9行后,插入新行
sed -e '9 a This is a new line' test.txt
或
sed '9 a This is a new line' test.txt

再次查看,发现sed并没有对源文件进行修改
- 在第2行前,插入新行
sed -e '2 i This is a new Line' test.txt
或
sed '2 i This is a new Line' test.txt

3.2.8 练习3-替换(-e,s,g,-i)
- 将所有行的root,替换成doug
sed -e 's/root/doug/g' test.txt
或
sed 's/root/doug/g' test.txt

- 将所有行的root,替换成doug,并修改源文件
sed -i 's/root/doug/g' test.txt
cat test.txt

3.2.9 练习4-删除(暂无)
3.3 格式化文本数据抽取工具-awk
3.3.1 简介
从处理一个具有一定格式的文本(格式化文本)中抽取数据,需要使用awk处理。之所以叫 AWK 是因为其取了三位创始人 Aho,Weinberger, Kernighan 的 首字符。
与sed相比,awk更擅长处理格式化文本。格式化文本一般使用某个特定的字符(称为与分隔符)将文本中不同的字段(称为域)隔开。
原理:
逐行读取文件,以分隔符将每行切片(默认为空格),切开的部分再进行后续处理
3.3.2 语法
awk [options] '[pattern] {action}' [input-file]
备注:[pattern]不止是正则表达式,还可以是BEGIN、关系表达式等等。
参考 man awk、霍格沃兹测试学院

3.3.3 常用参数
参数 | 全称 | 举例 | 说明 |
---|---|---|---|
-F | –field-separator | awk -F : ‘{print $0}’ /etc/passwd | 指定域分隔符,默认分隔符为空格 |
3.3.4 内置函数1
函数 | 说明 |
---|---|
输出 | |
3.3.5 练习1(-F,print,$)
-
获取/etc/passwd有关root关键字的所有行
先查看/etc/passwd文件内容
cat /etc/passwd

可以看出,/etc/passwd的文件每行以冒号“:”分隔。所以我们将冒号“:”作为分隔符。awk默认分隔符为空格。
语法:
awk [options] '[pattern] {action}' [input-file]
命令:
awk -F : '/root/ {print $0}' /etc/passwd

打印最后一列(第7列)
语法:
awk [options]'[pattern] {action}' [input-file]
命令:
awk -F : '/root/ {print $7}' /etc/passwd

说明:处理这个文件时,使用选项“F”指定域分隔符为冒号“:”,划分完后将这一行成为一条记录。这条记录的各个字段按顺序称为域1,域2…使用标识符“$1”表示第一个字段,“$2”表示第二个字段…。整条记录使用“$0”。
参考:《Linux命令、编辑器与Shell编程》/王刚、霍格沃兹测试学院
3.3.6 内置变量
变量 | 说明 |
---|---|
FILENAME | |
BEGIN | |
END | |
FS | 设置字段分隔符 |
NF | 列数 |
NR | 行数 |
RS | 设置记录分隔符,默认为新行 |
OFS | 设置分隔字段的字符,默认为空格 |
参考:Linux awk 命令 、《Linux命令、编辑器与Shell编程》/王刚
3.3.7 练习2(-F,NR,print,$)
- 打印/etc/passwd的11行
先查看/etc/passwd的所有信息
cat -n /etc/passwd

打印第11行
语法:
awk [options]'[pattern] {action}' [input-file] 备注:NR==11 属于pattern
命令:
awk -F : 'NR==11 {print $0}' /etc/passwd
或
awk 'NR==11 {print $0}' /etc/passwd

3.3.8 练习3(BEGIN,END,RS,FS)
- 输出文本头、尾
语法:
awk [options]'[pattern] {action}' [input-file] 备注:BENIN 和 END 属于pattern
命令:
awk -F : 'BEGIN {print "name bash\n----------"} /root/ {print $1,$7} END {print "----END----"}' /etc/passwd

-
设置“记录分隔符”
显示出看效果
echo "111 222|333 444|555 666"
再使用管道命令,传递给awk命令。先使用BEGIN语句,对文本先做处理,再进行输出
语法:
awk [options]'[pattern] {action}' [input-file] 备注:BENIN 属于pattern
命令:
echo "111 222|333 444|555 666" | awk 'BEGIN{RS="|"} {print $0}'

- 输出学生的姓名,各科成绩。
修改test.log文本,如下
20210222001#xiaohong#100#98#90#60
20210222002#xiaowang#90#88#69#70
20210222003#xiaoming#70#100#89#99
20210222004#xiaogang#100#99#80#100

设置字段分隔符(FS),记录分隔符(RS),并输出域2,域3,域4,域5,域6(如果列数多,可用for循环)
语法:
awk [options]'[pattern] {action}' [input-file] 备注:BENIN 属于pattern
命令:
awk 'BEGIN{FS="#";RS="\n\n"}{print $2,$3,$4,$5,$6}' test.log
或
awk -F# 'BEGIN{RS="\n\n"} {print $2,$3,$4,$5,$6}' test.log

格式化
语法:
awk [options]'[pattern] {action}' [input-file]
命令:
awk 'BEGIN{FS="#";RS="\n\n";print "name\t\tchinese\tmath\tenglish\tsports"}{print $2"\t"$3"\t"$4"\t"$5"\t"$6}' test.log
或
awk 'BEGIN{FS="#";RS="\n\n";OFS="\t"} {print $2,$3,$4,$5,$6}' test.log

备注:可以用end命令统计平均数。
3.3.4 常见算术运算符(暂时不用)
运算符 | 用途 | 运算符 | 用途 |
---|---|---|---|
= | 赋值 | y– | |
x+y | |||
x-y | |||
3.3.5 常见关系运算符和操作符(暂时不用)
关系运算符和操作符 | 说明 | 关系运算符和操作符 | 说明 |
---|---|---|---|
> | 大于 | != | 不等于 |
>= | 大于等于 | == | 等于 |
< | 小于 | ~/pattern/ | 匹配pattern |
<= | 小于等于 | !~/pattern/ | 不匹配pattern |
4. 三剑客实战
新建access.log文本,如下
127.0.0.1 - - [21/Jul/2020:01:10:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.2 - - [21/Jul/2020:15:10:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.2 - - [21/Jul/2020:16:10:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.3 - - [21/Jul/2020:17:10:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.3 - - [21/Jul/2020:21:11:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.3 - - [21/Jul/2020:21:12:27 +0800] "GET / HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.4 - - [21/Jul/2020:21:13:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.4 - - [21/Jul/2020:21:14:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.4 - - [21/Jul/2020:21:15:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.4 - - [21/Jul/2020:21:16:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.5 - - [21/Jul/2020:21:17:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.5 - - [21/Jul/2020:21:18:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.5 - - [21/Jul/2020:21:19:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.5 - - [21/Jul/2020:22:20:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.6 - - [21/Jul/2020:22:21:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.6 - - [21/Jul/2020:22:22:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.6 - - [21/Jul/2020:22:23:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.6 - - [21/Jul/2020:23:24:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.6 - - [21/Jul/2020:23:25:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.6 - - [21/Jul/2020:23:26:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:27:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:28:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:29:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:30:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:31:27 +0800] "GET / HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:32:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.7 - - [21/Jul/2020:23:33:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:33:27 +0800] "GET /getuser/123 HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:34:27 +0800] "GET /getproduct/234 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:35:27 +0800] "GET /addproduct/234 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:36:27 +0800] "GET /addproduct/345 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:37:27 +0800] "GET /pay/4567 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:38:27 +0800] "GET /home/5678 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:39:27 +0800] "GET /addproduct/123 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:40:27 +0800] "GET /home/23432 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.8 - - [21/Jul/2020:23:40:27 +0800] "GET /pay/2341 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.9 - - [21/Jul/2020:23:41:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.9 - - [21/Jul/2020:23:41:27 +0800] "GET / HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.10 - - [21/Jul/2020:23:42:27 +0800] "GET / HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.11 - - [21/Jul/2020:23:42:27 +0800] "GET / HTTP/1.1" 500 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.12 - - [21/Jul/2020:23:42:27 +0800] "GET / HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.13 - - [21/Jul/2020:23:43:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"
127.0.0.14 - - [21/Jul/2020:23:44:27 +0800] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" "-"

4.1 找出log中 404 和 500 的报错有多少条
查看404 和 500 的数据
grep -E '404|500' access.log
sed -rn '/404|500/p' access.log 备注用-E代替-r也可以,不知道为啥
awk '/404|500/{print $0}' access.log
或
awk '$9~/404|500/{print $0}' access.log 备注:按空格分隔,对第九列匹配



再统计
grep -E '404|500' access.log | wc -l
或
grep -Ec " 404 | 500 " access.log
sed -rn '/404|500/p' access.log | wc -l
awk '/404|500/{print $0}' access.log | wc -l
或
awk '$9~/404|500/{print $0}' access.log | wc -l 备注:按空格分隔,对第九列匹配

4.2 访问量最高的前5名IP
新增三个Linux命令说明
- 去重复命令 uniq
选项 | 说明 |
---|---|
c | 输出重复行的重复次数 |
备注:使用去重时,先使用sort排序(不加任何参数),排序后可使用sort添加参数再排序。因为uniq只对紧邻的数据去重。例如:abbbc去重后abc;abbbcbdb去重后abcbdb,所以要先sort排序为abbbbbcd,再去重为abcd。
参考《Linux命令、编辑器与Shell编程》/王刚
- 排序命令sort
选项 | 说明 |
---|---|
k | 指定需要排序的列 |
n | 依照数值的大小排序 |
r | 以相反的顺序来排序 |
参考:LInux之Shell工具:Cut、Sed、Awk、Sort
- 查看文件开头部分head
选项 | 说明 |
---|---|
-n | k,显示文档开始的前k行,-k,不显示文档结尾的最后 k 行 |
参考:Linux之head命令
awk '{print $1}' access.log | sort | uniq -c | sort -k 1 -nr | head -n 5
grep -Eo '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' access.log | sort | uniq -c | sort -k 1 -nr | head -n 5
或
grep -Eo '^([0-9]+\.){3}[0-9]+' access.log | sort | uniq -c | sort -k 1 -nr | head -n 5
或
grep -Eo "^[0-9]+(\.[0-9]+){3}" access.log | sort | uniq -c | sort -k 1 -nr | head -n 5


4.3 查看某一时间段的IP访问量(20-23点)
awk '/21\/Jul\/2020:2[0-9]+/ {print $1}' access.log | sort | uniq -c | wc -l
或
grep -E "21/Jul/2020:2\d*" access.log | awk '{print $1}' | sort | uniq -c | wc -l
备注:为啥不能写成\d+,不解
或
grep -E "21/Jul/2020:2+" access.log | awk '{print $1}' | sort | uniq -c | wc -l


4.4 查看访问5次以上的IP
awk '{print $1}' access.log | sort | uniq -c | awk '{if($1>5) print $0}' | sort -k 1 -nr

4.5 查询某个IP的详细访问情况,按访问频率排序
awk '/127.0.0.8/ {print $7}' access.log | awk -F / '{print $2}' | sort | uniq -c | sort -k 1 -nr
或
awk 'BEGIN{FS="/"} /127.0.0.8/ {print $4}' access.log | sort | uniq -c | sort -k 1 -nr

4.6 将127.0.0.8 页面地址后面的数字替换成xxx
grep "127.0.0.8" access.log | sed -r 's/\/[0-9]+ HTTP/\/xxx HTTP/g' access.log
或
grep "127.0.0.8" access.log | sed -r 's#/[0-9]+ HTTP#/xxx HTTP#g'
或
sed -n '/127.0.0.8/p' access.log | sed -n 's#/[0-9]* HTTP#/xxx HTTP#p'
备注:分隔符除了/还可以是很多符号,可以自行尝试

参考
三剑客实战参考:nginx 日志查看、霍格沃兹测试学院
工具
虚拟机:VMware Workstations 16 Pro
Linux:CentOS 7
截图工具:FSCapture 8.4
文档编写工具:Typora
PS: 如果本文对您有帮助,请单击文章最后左下角的“点赞”或留言。
PPS:本人水平有限,难免出现错误。如您发现错误,请批评指正。