linux - awk - 文本统计命令

使用awk命令,可以处理一下任务:
    管理小型个人数据库
    产生报告
    验证数据
    产生索引并执行其他文档准备任务
    测试算法    
    提取数据片段进行处理
    排序数据
    执行简单的网络通讯
    分析和调试awk程序
    用C或C ++编写的函数扩展语言

官网:
​​​     http://www.gnu.org/software/gawk/manual/gawk.html​

一、语法
    awk '{pattern + action}' {filenames}
        查单个文件
    awk '{pattern + action}' {filenames} {filenames} {filenames} ...
        查多个文件
    awk 'BEGIN{pattern + action} {pattern + action} END{action}'
        BEGIN 块初始化调用一次
        END 块结束时调动一次
    多行命令
awk 'BEGIN{
 print 1
}'
(注:缩进使用空格,不能用tab;)

二、操作符
    赋值运算符:=、+=、-=、*=、/=、^=、**=、%=
    逻辑运算符:||、&&、!
    正则运算符:~、!~
    关系运算符:<、<=、>、>=、!=、==
    算数运算符:+、-、*、/、%、++、--、^
    其他运算符:$(字段引用)、?:(三目运算)、in(是否存在某值)

三、常用内容变量
    $0:当前记录
    $1~$n:第n个字段
    FS:输入分隔符,默认空格
    RS:行结束分隔符,默认换行符 \n
    NF:字段数
    NR:行号,从 1 开始
    OFS:输出分隔符,默认空格
    ORS:输出记录分隔符,默认换行符

四、常见实例

统计所有 cvs 文件行数
awk '{row+=1} END {print "行数",row}' *.csv

统计目录下所有文件占用的字节数
ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ",size}'

统计 accesslog
awk '{print $7}'  access_log2020-11-*.log | sort | uniq -c
awk '{arr[$7]+=1} END{for(k in arr){print arr[k]"\t"k}}' access_log2020-11-*.log

连接状态汇总
netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print a,s[a]}'

五、实例

--算数运算测试
awk 'BEGIN{print 1+2}'


--执行多行命令:
awk '{
print "abc"
}'

--while 循环:
awk '
BEGIN{
i=1
while(i<3){
print "loop",i
i++
}
}'

--for 循环:
awk '
BEGIN{
for(i=0;i<5;i++){
print "loop",i
}
}
'

for (i in array)
do something with array[i]



--分隔符 FS (同 -F 参数)
awk 'BEGIN{FS=":"}{print $1,$1}' /etc/passwd


--正则实例
awk 'BEGIN{a="100testaa";if(a~/100/){print "ok"}}' --变量 a 中是否存在 100
awk -F':' 'BEGIN{ct=0;} {if($0~/\d+/){ ct++;print $0;}} END{print ct;}' /etc/passwd --查找包含数字的行

--遍历数组:
awk '
BEGIN{
arr[0]="aa"
arr[1]="bb"
arr[2]="cc"
print("length=",length(arr))
for(i in arr){
printf("loop i=%s key=%s val=%s\n",i,i,arr[i])
}
}
'

--数组排序:
asort 是对数组的值进行排序,并且会丢掉原先键值;
asorti是对数组的下标进行排序。

awk '
BEGIN{
print("对数组值排序")
arr[0]=111
arr[1]=222
arr[2]=333
n = asort(arr)
for(i=1;i<=n;i++)
print(arr[i])
}
'

awk '
BEGIN{
print("对数组键排序")
arr[0]=111
arr[1]=222
arr[2]=333
n = asorti(arr)
for(i=1;i<=n;i++)
print(arr[i])
}
'

awk '
BEGIN{
print("对数组值排序,原数组不变")
arr[0]=111
arr[1]=222
arr[2]=333
n = asort(arr,newArr)
for(i=1;i<=n;i++)
print(newArr[i])
}
'

awk '
BEGIN{
print("对数组键排序,原数组不变")
arr[0]=111
arr[1]=222
arr[2]=333
n = asorti(arr,newArr)
for(i=1;i<=n;i++)
print(newArr[i])
}
'

--自定义函数
数组合并为字符串(自定义 join() 方法)
awk '
function join(array, start, end, sep, result, i)
{
if (sep == "")
sep = " "
else if (sep == SUBSEP) # magic value
sep = ""
result = array[start]
for (i = start + 1; i <= end; i++)
result = result sep array[i]
return result
}
BEGIN{
arr[0]="aa"
arr[1]="bb"
arr[2]="cc"
for(i in arr){
printf("loop i=%s key=%s val=%s\n",i,i,arr[i])
}
str = join(arr,0,2,",")
print("合并后:",str)
}
'