1.一般按照行匹配
文本流的行内匹配,awk支持的包括:
- 通用的Linux正则匹配,文本匹配的格式是/pattern/,类似sed 的匹配方式
# awk -F : '/root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# awk -F : '/^root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
- 运算符匹配
awk -F : '$3<10{print $0}' /etc/passwd
满足条件的$3<10才会打印改行。
- 使用正则匹配范围,此时和sed 用法一样
#!/bin/bash
# sed按照时间段截取,使用模式匹配,中间用逗号分开
# sed -n '/开始时间/,/结束时间/' 被截取日志原文件名称>截取后存储日志文件名称
logfile=/data/scripts/op_log/error.hrms.xxxx.lab.log
sed -n '/2022\/06\/16/,/2022\/08\/01/p' $logfile
# awk 按时间截取日志,并打印出第一列
awk '/2022\/07\/29/,/2022\/08\/01/{print $1}' $logfile
忽略大小写的方法
[root@VM-0-9-centos ser1]# ps aux | awk 'BEGIN{IGNORECASE=1} $8~/t/{print $0}'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
git 13543 95.0 0.0 313940 4 ? Tl Jul18 28649:27 runsv puma
2.按列匹配
awk多列匹配,使用了域变量和正则表示
[hadoop@st1 data]$ netstat -an|awk '$1~/tcp/&&$3~/64/{print $0}'
tcp 0 64 10.0.0.208:22 10.0.0.1:55576 ESTABLISHED
#$1~/tcp/ 表示匹配第一个域中包含 tcp 的行,然后用 && 连接起来,表示与关系。
也可以使用if 语句
[root@VM-0-9-centos ~]# ps aux | awk '$8=="S+" {print $0}'
root 12612 0.0 0.0 14964 0 pts/0 S+ Mar05 0:00 /bin/bash
root 31784 0.0 0.0 117000 1032 pts/0 S+ 22:36 0:00 bash
#使用if语句也可也达到同上的效果
[root@VM-0-9-centos ~]# ps aux | awk '{if($8=="S+") print $0}'
root 12612 0.0 0.0 14964 0 pts/0 S+ Mar05 0:00 /bin/bash
root 31784 0.0 0.0 117000 1032 pts/0 S+ 22:36 0:00 bash
shell 和 awk 中 if 语句中的判断 也可以使用正则表达式
#还是判断 $8 中是否包含 "S+",不过+得转义成正常的字符
[root@VM-0-9-centos ~]# ps aux | awk '{if($8 ~/S\+/) print $0}'
root 12612 0.0 0.0 14964 0 pts/0 S+ Mar05 0:00 /bin/bash
root 31784 0.0 0.0 117000 1032 pts/0 S+ 22:36 0:00 bash
这里shell 和 awk 也有一些小区别
shell 中判断 字符 string 是否在 在变量中,可以写成if [[ $var =~ "string" ]]
而awk 中 不能使用 “=~”