🚀 1.awk介绍
🌈 1.1 什么是AWK
对于接触过Linux操作系统的人来说,应该都听过说Linux中的文本三剑客吧,即awk、grep、sed,也是必须要掌握的Linux命令之一,三者都是用来处理文本的,但侧重点各不相同,awk功能最强大,但也最复杂
awk是一种编程语言,用于在Linux/Unix下对文本和数据进行处理,数据可以来自标准输入、一个或多个文件,或其他命令的输出,它支持用户自定义函数和动态正则表达式等先进功能,是Linux/Unix下的一个强大编程工具,它在命令行中使用,但更多是作为脚本来使用。
awk有很多内建的函数,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优点。
🌈 1.2 AWK 的工作流程
AWK 工作流程可分为三个部分:
读输入文件之前执行的代码段(由BEGIN关键字标识)。
主循环执行输入文件的代码段。
读输入文件之后的代码段(由END关键字标识)。
命令结构
awk ‘BEGIN{ commands } pattern{ commands } END{ commands }’
🚀 2.awk实战案例
🌈 2.1 格式化空白
🚩 移除每行的前缀、后缀空白,并将各部分左对齐。
aaaa bbb ccc bbb aaa ccc ddd fff eee gg hh ii jj
awk ‘BEGIN{OFS=“\t”}{$1=$1;print}’ a.txt
✨✨ 执行结果:
aaaa bbb ccc bbb aaa ccc ddd fff eee gg hh ii jj
🌈 2.2 根据某字段去重
🚩 去掉uid=xxx重复的行。
2022-01-13_12:00_index?uid=123
2022-01-13_13:00_index?uid=123
2022-01-13_14:00_index?uid=333
2022-01-13_15:00_index?uid=9710
2022-01-14_12:00_index?uid=123
2022-01-14_13:00_index?uid=123
2022-01-15_14:00_index?uid=333
2022-01-16_15:00_index?uid=9710
awk -F"?" ‘!arr[$2]++{print}’ a.txt
✨✨ 执行结果
2022-01-13_12:00_index?uid=123
2022-01-13_14:00_index?uid=333
2022-01-13_15:00_index?uid=9710
🌈 2.3 统计次数
🚩 统计文本中出现的次数
portmapper portmapper portmapper portmapper portmapper portmapper status status mountd mountd mountd mountd mountd mountd
awk ‘{arr[$1]++}END{OFS=“\t”;for(idx in arr){printf arr[idx],idx}}’ a.txt
✨✨ 执行结果
6: portmapper 2: status 6: mountd
🌈 2.4 行转列
🚩 将以下文本行转列
name age alice 21 ryan 30
awk ’
{
for(i=1;i<=NF;i++){
if(!(i in arr)){
arr[i]=KaTeX parse error: Expected 'EOF', got '}' at position 11: i }̲ else { …i
}
}
}
END{
for(i=1;i<=NF;i++){
print arr[i]
}
}
’ a.txt
✨✨ 执行结果
name alice ryan age 21 30
🌈 2.5 列转行
🚩 就是只要第一列数字相同, 就把他们的第二列放一行上,中间空格分开
74683 1001 74683 1002 74683 1011 74684 1000 74684 1001 74684 1002 74685 1001 74685 1011 74686 1000 .... 100085 1000 100085 1001
if($1 in arr){
arr[$1] = arr[$1]" "$2
} else {
arr[$1] = $2
}
}
END{
for(i in arr){
printf “%s %s\n”,i,arr[i]
}
}
✨✨ 执行结果
74683 1001 1002 1011 74684 1000 1001 1002 ...
🌈 2.6 统计多项数据
🚩如下内容,第一个字段是IP,第二个字段是每个访问的uri。
要求统计出每个ip访问的总次数,以及每个ip所访问的uri的次数。
1.1.1.1 /index1.html 1.1.1.1 /index1.html 1.1.1.1 /index2.html 1.1.1.1 /index2.html 1.1.1.1 /index2.html 1.1.1.1 /index3.html 1.1.1.2 /index1.html 1.1.1.2 /index2.html 1.1.1.2 /index2.html 1.1.1.3 /index1.html 1.1.1.3 /index1.html 1.1.1.3 /index2.html 1.1.1.3 /index2.html 1.1.1.3 /index2.html 1.1.1.3 /index3.html 1.1.1.3 /index3.html 1.1.1.4 /index2.html 1.1.1.4 /index2.html
使用复合索引的数组
awk ’
{
a[$1]++
b[$1"“$2]++
}
END{
for(i in b){
split(i,c,”");print c[1],a[c[1]],c[2],b[i]
}
}’ a.log
✨✨ 执行结果
1.1.1.1 6 /index3.html 1 1.1.1.1 6 /index2.html 3 1.1.1.1 6 /index1.html 2 1.1.1.2 3 /index2.html 2 1.1.1.2 3 /index1.html 1 1.1.1.3 7 /index3.html 2 1.1.1.3 7 /index2.html 3 1.1.1.3 7 /index1.html 2 1.1.1.4 2 /index2.html 2
🚀 3.awk常用命令
🌈 3.1 awk查看某个时间段的日志
awk ‘/^开始时间日期/,/^结束时间日期/’ nginx.log awk支持正则表达式,比如,查询时间段2021-03-24 10:12:12 到 2021-09-24 10:12:12, 可以用awk ‘/^2021-03-24 10:12:*/,/^2021-09-24 10:12:*/’ nginx.log查询。
🌈 3.2 统计命令
# 求和 cat data|awk '{sum+=$1} END {print "Sum = ", sum}' # 求平均 cat data|awk '{sum+=$1} END {print "Average = ", sum/NR}' # 求最大值 cat data|awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}' # 求最小值(min的初始值设置一个超大数即可) awk 'BEGIN {min = 1999999} {if ($1<min) min=$1 fi} END {print "Min=", min}'
🌈 3.3 awk 内置变量表
🌈 3.5 awk 字符串函数
🌈 3.6 其他
1、打印文件的第一列(域) : awk ‘{print $1}’ filename
2、打印文件的前两列(域) : awk ‘{print $1,$2}’ filename
3、打印完第一列,然后打印第二列 : awk ‘{print $1 $2}’ filename
4、打印文本文件的总行数 : awk ‘END{print NR}’ filename
5、打印文本第一行 :awk ‘NR==1{print}’ filename
6、打印文本第二行第一列 :sed -n “2p” filename | awk ‘{print $1}’