主要用作数据分段处理(默认空白分隔)
awk 基本语法
- awk 是 linux 下的一个命令,同时也是一种语言解析引擎
- awk 具备完整的编程特性。比如执行命令,网络请求等
- 精通 awk,是一个 linux 工作者的必备技能
- 语法
awk 'pattern{action}'
awk 上下文变量
- 开始 BEGIN 结束 END
- 行数 NR
- 字段与字段数 $1 $2 … $NF NF
- 整行 $0
- 字段分隔符 FS
- 输出数据的字段分隔符 OFS
- 记录分隔符 RS
- 输出字段的行分隔符 ORS
字段变量用法
- -F 参数指定字段分隔符,可以用|指定多个- 多分隔符 -F ‘<|>’
- BEGIN{FS=“_”} 也可以表示分隔符
- $0 代表当前的记录
- $1 代表第一个字段
- $N 代表第 N 个字段
- $NF 代表最后一个字段
- $(NF-1) 代表倒数第二个字段
pattern 表达式
- 正则匹配
$1~/pattern/
/pattern/
- 比较表达式
$2>2
$1=="b"
awk pattern 匹配表达式案例
- 开始和结束
awk 'BEGIN{}END{}'
- 正则匹配
- 整行匹配
awk '/Running/'
- 字段匹配
awk '$2~/xxx/'
- 整行匹配
- 行数表达式
- 取第二行
awk 'NR==2'
- 去掉第一行
awk 'NR>1'
- 取第二行
- 区间选择
awk '/aa/,/bb/'
awk '/1/,NR==2'
[jck287213@shell.ceshiren.com ~]$ echo '1
2
3’
1
2
3
[jck287213@shell.ceshiren.com ~]$ echo ‘1
2
3’ | awk ‘NR==1’(取第一行)
1
[jck287213@shell.ceshiren.com ~]$ echo ‘1
2
3’ | awk ‘NR==2’(取第二行)
2
[jck287213@shell.ceshiren.com ~]$ echo ‘1
2
3’ | awk ‘$1~/2/’(第1字段匹配2)
2
[jck287213@shell.ceshiren.com ~]$ echo ‘1
2
3’ | awk ‘/2/’(整行匹配2))
2
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt
ck141906 pts/0 120.52.147.49
ck140081 pts/13 113.65.231.23
ck140081 pts/12 113.65.231.23
ck140081 pts/4 221.219.101.182
82894931 pts/12 36.112.85.179
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘NR==1,NR==3{print $0}’( 1. #打印1-3行的行内容)
ck141906 pts/0 120.52.147.49
ck140081 pts/13 113.65.231.23
ck140081 pts/12 113.65.231.23
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘(NR>=1)&&(NR<=3){print $0}’( 1. #打印1-3行的行内容,&&表示“与”)
ck141906 pts/0 120.52.147.49
ck140081 pts/13 113.65.231.23
ck140081 pts/12 113.65.231.23
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘(NR==1)||(NR==3){print $0}’ ( 1. #打印第1行或第3行的行内容,|| 表示“或”)
ck141906 pts/0 120.52.147.49
ck140081 pts/12 113.65.231.23
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘NR>4{print $0}’( 1. #打印行号大于4的行内容)
82894931 pts/12 36.112.85.179
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘!(NR>4){print $0}’( 1. #打印行号小于4的行内容,!表示取反)
ck141906 pts/0 120.52.147.49
ck140081 pts/13 113.65.231.23
ck140081 pts/12 113.65.231.23
ck140081 pts/4 221.219.101.182
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘(NR%2)==1{print $0}’(输出奇数行)
ck141906 pts/0 120.52.147.49
ck140081 pts/12 113.65.231.23
82894931 pts/12 36.112.85.179
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘(NR%2)==0{print $0}’(输出偶数行)
ck140081 pts/13 113.65.231.23
ck140081 pts/4 221.219.101.182
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘/^ck141/{print $0}’(输出以ck141开头的内容)
ck141906 pts/0 120.52.147.49
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt | awk ‘/182$/{print $0}’(输出以182结尾的内容)
ck140081 pts/4 221.219.101.182
[jck287213@shell.ceshiren.com test]$ echo ‘a 1
b 2
c 3’ | awk ‘/a/,/c/’(输出以a开头以c结尾之间的行的数据)
a 1
b 2
c 3
[jck287213@shell.ceshiren.com test]$ echo ‘1
2
3’ | awk ‘/1/’
1
[jck287213@shell.ceshiren.com test]$ echo ‘1
2
3’ | awk ‘/1/,NR==2’(整行匹配1,并且输出第2行)
1
2
[jck287213@shell.ceshiren.com test]$ echo ‘1
2
3’ | awk ‘/1/,NR==3’(整行匹配1,并且输出2行和3行)
1
2
3
action 行为表达式 {action}
- 打印
{print $0}
{print $2}
- 赋值
{$1="abc"}
- 处理函数
- 原始内容 $0
- 更新后内容
{$1=$1;print $0}
[jck287213@shell.ceshiren.com test]$ echo ‘a b c d’ | awk ‘{OFS=“|”;$1=$1;print $0}’
a|b|c|d
[jck287213@shell.ceshiren.com test]$ echo ‘a b c d’ | awk ‘{print $0;OFS=“|”;$1=$1;print $0}’
a b c d
a|b|c|d
单行转多行
echo 1:2:3 | awk ‘BEGIN{RS=“:”}{print $0}’
1
2
3
[jck287213@shell.ceshiren.com test]$ echo 1:2:3|awk ‘BEGIN{RS=“:”}{print $0}’
1
2
3
多行变单行
echo '1
2
3' | awk 'BEGIN{RS="";FS="\n";OFS=":"}{$1=$1;print $0}'
1:2:3
[jck287213@shell.ceshiren.com test]$ echo ‘1
2
3’|awk ‘BEGIN{RS=“”;FS=“\n”;OFS=“:”}{$1=$1;print$0}’
1:2:3
echo '1
2
3' | awk 'BEGIN{ORS=":"}{$1=$1;print $0}'
1:2:3:
计算平均数
echo ‘1,10
2,20
3,30’ | awk ‘BEGIN{total=0;FS=“,”}{total+=$2}END{print total/NR}’
20
awk 的词典结构 array
- array 是稀疏矩阵,类似 python 的词典类型
- 统计多家机构的营业额
- 统计多家机构的营业额平均值
echo ‘a, 1, 10
a, 2, 20
a, 3, 30
b, 1, 5
b, 2, 6
b, 3, 7’ | awk ‘{data[$1]+=$3}
END{for(k in data) print k,data[k]}’
a, 60
b, 18
echo ‘a, 1, 10
a, 2, 20
a, 3, 30
b, 1, 5
b, 2, 6
b, 3, 7’ | awk ‘{data[$1]+=$3;count[$1]+=1;}
END{for(k in data) print k,data[k]/count[k]}’
a, 20
b, 6
[jck287213@shell.ceshiren.com test]$ head -5 uniq_demo.txt | awk ‘{OFS=" % ";$1=$1;print $0}’(指定分隔符输出)
ck141906 % pts/0 % 120.52.147.49
ck140081 % pts/13 % 113.65.231.23
ck140081 % pts/12 % 113.65.231.23
ck140081 % pts/4 % 221.219.101.182
82894931 % pts/12 % 36.112.85.179
[jck287213@shell.ceshiren.com test]$ top -b -n 1 | grep Cpu( 1. # -b -n 1 表示只需要1次输出结果)
%Cpu(s): 3.0 us, 3.0 sy, 0.0 ni, 93.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
[jck287213@shell.ceshiren.com test]$ top -b -n 1 | grep Cpu | awk -F “,” ‘{print $4}’( 1. #输出cpu空闲率的字段)
85.7 id
[jck287213@shell.ceshiren.com test]$ head -5 uniq_demo.txt | awk -F " " ‘{print $3}’(获取第三段内容)
120.52.147.49
113.65.231.23
113.65.231.23
221.219.101.182
36.112.85.179
[jck287213@shell.ceshiren.com tetop -b -n 1 | grep Cpu | awk -F “,” ‘{print $4}’$3}’
90.9 id
[jck287213@shell.ceshiren.com test]$ top -b -n 1 | grep Cpu | awk -F “,” ‘{print $4}’| awk ‘{print $1}’(#输出Cpu空闲率))
87.9
显示时间
[jck287213@shell.ceshiren.com test]$ date +“%Y%m%d”
20231012
[jck287213@shell.ceshiren.com test]$ date +“%Y%m01”
20231001
[jck287213@shell.ceshiren.com test]$ date +“%F %H:%M:%S”
2023-10-12 22:47:32
过滤文本中重复行数
[jck287213@shell.ceshiren.com test]$ head -n 5 uniq_demo.txt |awk ‘{print $3}’| awk ‘{a[$1]++}END{fiin a){print i,a[i]}}’
36.112.85.179 1
113.65.231.23 2
221.219.101.182 1
120.52.147.49 1
[jck287213@shell.ceshiren.com test]$ head -n 5 /etc/passwd | awk ‘//bin/bash$/{print $0}’
root0:0:root:/root:/bin/bash
[jck287213@shell.ceshiren.com test]$ cat /etc/p | awk ‘/^root/{print $0}’(#输出以 root 开头的行)
root0:0:root:/root:/bin/bash
[jck287213@shell.ceshiren.com test]$ cat /etc/passwd | awk -F “:” ‘/^root/{print $1,$3,$NF}’(#加上bin要使用反斜杠输出以bash结尾的行)
root 0 /bin/bash
[jck287213@shell.ceshiren.com test]$ grep -c “/bin/bash$” /etc/passwd(统计以/bin/bash 结尾的行数)
8496
[jck287213@shell.ceshiren.com test]$ awk ‘/bin/bash/ {print | “wc -l”}’ /etc/passwd(统计以/bin/bash 结尾的行数)
8496