前言
Linux 三剑客:grep, sed, awk
grep 更适合单纯的查找或匹配文本
sed 更适合编辑匹配到的文本
awk 更适合格式化文本,或对文本进行复杂的数据处理
grep
参数说明
-E
: 使用正则表达式
-r
: 搜索目录时使用
-l
: 查询文件名称时使用,而不是文件内容
-o
: 只展示匹配内容
在文件中查找字符串
# 查找含有单个字符串的所有行
grep "xxx" filename
# 查找含有多个字符串的所有行
grep "xxx\|yyy" filename
# 取反搜索。查找不包含某个字符串的行
grep -v "xxx" filename
# 查找目录下包含某个字符串的文件
grep -r "xxx" /data/zero-app
# 统计文件中含有某个字符串的行数
grep -c "xxx" filename
# 忽略大小写
grep -i "XXX" filename
# 显示匹配行的上下文
# -B n 显示前几行
# -A n 显示后几行
# -C n 显示前后几行
grep -A 7 "xxx" filename
# 只显示匹配的字符串
grep -o "xxx" filename
# 显示匹配行的行号
grep -n "xxx" filename
# 开启正则
grep -E "^xxx$" filename
grep 实践
# 日志信息查找
cat xxx.log | grep "error"
# 查找目录下包含字符串的所有文件,而不是展示内容。logdir 表示某个文件夹
grep -lr "xxx" /logdir
# 过滤搜索的文件类型
grep "xxx" --include "*.log" /logdir
grep "yyy" --exclude "*.txt" /logdir
# 将匹配行输出到其他文件
grep "xxx" a.txt | tee b.txt
# 查找多个文件
grep "xxx" a.txt b.txt c.txt
# 查找空白行
grep "^$" a.txt
# 根据时间范围查询。也可以使用 sed -n /起始时间/,/结束时间/p
grep "2023-08-09 23:59:59.[0-999]" errors.log
sed
sed 常用来做对文件的便捷 增删改 操作
如果不输入行号,则默认对每一行都操作
参数说明
-e
: 用于多点编辑
-i
: 直接修改文件内容
-f
: 运行一个 sed 脚本文件
-n
: 只展示结果
-r
: 支持正则
cat testfile
################################################################
# 动作说明
# a - 新增,也就是 append 的意思。在下一行插入
sed -e '4a # This is test'
# i - 插入,也就是 insert 的意思。在上一行插入
sed -e '4i # This is test2'
# d - 删除,也就是 delete 的意思。注意删的是 一行
set -e '2,5d'
# c - 替换,支持字符串。会取代整行,以行为单位的替换
sed -e '3c xxx'
# s - 替换,支持正则
sed -e 's/要被替换的字符串/新的字符串/g'
# p - 打印,也就是 print 的意思。通常 p 会与 sed -n 一起运行
set -n '5,7p'
sed 实践
# 在第四行后 添加一行
sed -e '4a newLine' testfile
# 在第二行后,加一行:drink tea
cat testfile -n | sed -e '2a drink tea'
# 在第二行后,加两行:drink tea, drink coffee
cat testfile -n | sed -e '2a drink tea ... \n drink coffe'
# 列出 testfile 的内容并且列出行号,同时,删除第2-5行
nl testfile | sed -e '2,5d'
# 删除 第3行 到 最后一行
nl testfile | sed -e '3,$d'
# 将第 2-5 行的内容取代成为 No 2-5 number
nl testfile | sed -e '2,5c No 2-5 Number'
# 搜索 有 `oo` 的行
nl testfile | sed -n '/oo/p'
# 删除所有包含 `oo` 的行
nl testfile | sed '/oo/d'
# 将所有 oo 替换成 kk
nl testfile | sed -e 's/oo/kk/g'
# 根据时间范围查询日志。逗号作为范围连接符
sed -n '/2023-08-09 23:58/,/2023-08-09 23:59/p' errors.log
awk
awk 常用来做一些对数据进行二次加工的操作
参数说明
-F
: 指定分隔符
$0
: 完整的输入内容。一般是每一行的内容
$n
: 匹配的参数,从 0 开始
NR
: 行号
NF
: 分割后的数组长度,一般配合 $NF
取值用
-f
: 指定 awk 脚本文件
-v a=1
: 设置变量 a=1
OFS
: 指定输出分割符
BEGIN{ 执行前的语句 }
: 执行前的语句
{ 每一行要执行的语句 }
: 每一行要执行的语句
END{ 执行后的语句 }
: 执行后的语句
awk 格式
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
awk 实践
# 假设有一个 log.txt。内容如下
# 2 this is a test
# 3 Do you like awk
# This's a test
# 10 There are orange,apple,mongo
# 按空格分割,输出文本中的 1,4 项
awk '{print $1, $4}' log.txt
# 自定义变量 a=2,并让每行匹配到的数据去 加a
awk -v a=2 '{print $1, $1+a}' log.txt
# 输出 行号大于2 的内容
awk '{if (NR > 2) { print $0 }}' log.txt
综合练习题
1、找出/proc/meminfo文件中以s开头的行,至少用三种方式,忽略大小写
cat /proc/meminfo | grep '^[sS]'
cat /proc/meminfo | sed -n '/^[sS]/p'
cat /proc/meminfo | awk '/^[sS]/'
2、显示当前系统上的以root,centos或者user开头的信息
cat /etc/passwd | grep -E '^(root|centos|user)'
cat /etc/passwd | awk -F: '/^(root|centos|user)/{ print $0}'
3、找出/etc/init.d/functions文件下包含小括号的行
cat /etc/init.d/functions | grep -E '\(|\)'
4、输出指定目录的基名
pwd | awk -F/ '{print $NF}'
5、找出网卡信息中包含的数字
cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep -E '[0-9]*'
6、找出/etc/passwd下每种解析器的用户个数
cat /etc/passwd | awk -F: '{print $NF}' | sort | uniq -c
7、过滤网卡中的ip,用三种方式实现
ip a | grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'
8、搜索/etc目录下,所有的.html或.php文件中main函数出现的次数
9、过滤掉php.ini中注释的行和空行
10、找出文件中至少有一个空格的行
grep -E '\ +' log.txt
11、过滤文件中以#开头的行,后面至少有一个空格
12、查询出/etc目录中包含多少个root
grep -roE 'root' /etc/ | wc -l
13、查询出文件中所有的qq邮箱
grep -E 'qq\.com$' log.txt
14、查询系统日志中所有的error
grep -Eir 'error' /var/log/
15、删除某文件中以s开头的行的最后一个词
sed -e 's/^s/'
16、删除一个文件中的所有数字
nl testfile | sed -e 's/[0-9]//g'
17、显示奇数行
nl testfile | awk 'NR%2==1 {print $0}'
18、删除passwd文件中以bin开头的行到nobody开头的行
19、从指定行开始,每隔两行显示一次
20、每隔5行打印一个空行
nl testfile | awk '{if (NR % 5 == 0){ print " "}; print $0}'
21、不显示指定字符的行
22、将文件中1到5行中aaa替换成AAA
nl testfile | sed '1,5{s/aaa/AAA}'
23、显示用户id为奇数的行
24、显示系统普通用户,并打印系统用户名和id
25、统计nginx日志中访问量(ip唯独计算)
26、实时打印nginx的访问ip
参考链接
Linux sed 命令
Linux awk 命令
blog.csdn.net/Cdy126/arti…
www.cnblogs.com/90s-blog/p/…
www.cnblogs.com/marit/p/173…