30_awk

发布时间 2023-10-23 01:32:29作者: 鸟叔书
1. 基本用法
[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" '{print $1"_"$2"_"$3}'
root_x_0
bin_x_1
daemon_x_2
adm_x_3
[root@kvm ckh]# cat 1.txt | awk -F":" '{print $1 $2 $3}'
rootx0
binx1
daemonx2
admx3
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" '{print "$1 $2 $3"}'
$1 $2 $3
$1 $2 $3
$1 $2 $3
$1 $2 $3
[root@kvm ckh]# cat 1.txt | awk -F":" '{print "$1__$2__$3"}'
$1__$2__$3
$1__$2__$3
$1__$2__$3
$1__$2__$3
2. NF NR
# NR 文件当前行的行号
# NF 文件当前行的列数(有几列)

[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" '{print "第"NR"行,共"NF"列"}'
第1行,共7列
第2行,共7列
第3行,共7列
第4行,共7列

3. $0, 不管分隔符是什么,始终打印全部
[root@kvm ckh]# cat 1.txt | awk -F":" '{print $0}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

4. 多个分隔符
# root:x:0:0:root:/root:/bin/bash

# 第一遍 :
root x 0 0 root /root /bin/bash
# 第二遍: /
root x 0 0 root " " root " " bin bash

# 验证
[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# head -1 1.txt | awk -F"[:/]" '{print $5}'
root
[root@kvm ckh]#
[root@kvm ckh]# head -1 1.txt | awk -F"[:/]" '{print $7}'
root
[root@kvm ckh]# head -1 1.txt | awk -F"[:/]" '{print $8}'

[root@kvm ckh]# head -1 1.txt | awk -F"[:/]" '{print $9}'
bin
[root@kvm ckh]# head -1 1.txt | awk -F"[:/]" '{print $11}'

[root@kvm ckh]# head -1 1.txt | awk -F"[:/]" '{print $10}'
bash

# 用或者 |
[root@kvm ckh]# head -1 1.txt | awk -F"[:|/]" '{print $5}'
root
[root@kvm ckh]# head -1 1.txt | awk -F"[:|/]" '{print $6}'

[root@kvm ckh]# head -1 1.txt | awk -F"[:|/]" '{print $7}'
root
[root@kvm ckh]# head -1 1.txt | awk -F"[:|/]" '{print $8}'

[root@kvm ckh]# head -1 1.txt | awk -F"[:|/]" '{print $9}'
bin
[root@kvm ckh]# head -1 1.txt | awk -F"[:|/]" '{print $10}'
bash
5. awk 添加搜索
[root@kvm ckh]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        4.0M     0  4.0M   0% /dev
tmpfs            12G     0   12G   0% /dev/shm
tmpfs           4.7G  1.2M  4.7G   1% /run
/dev/sda1        60G  7.6G   53G  13% /
tmpfs           2.4G  4.0K  2.4G   1% /run/user/0
[root@kvm ckh]#
[root@kvm ckh]# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        60G  7.6G   53G  13% /
[root@kvm ckh]#
[root@kvm ckh]# df -h / | awk '{print $4}'
Avail
53G
[root@kvm ckh]#
[root@kvm ckh]# df -h / | awk '/dev/{print $4}'
53G
[root@kvm ckh]#
[root@kvm ckh]# df -h / | grep "dev" | awk '{print $4}'
53G
[root@kvm ckh]# df -h / | awk '/^\//{print $4}'          # 正则,转义
53G
[root@kvm ckh]# df -h / | awk '/^\//{print $4}' | sed 's/G//'
53
[root@kvm ckh]# cat 1.txt | awk -F":" '/(^root|^bin)/{print}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" '/(^root|^bin)/{print $0}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" '/(^root|^bin)/{print $1}'
root
bin
6.awk 完整的格式
# awk 'BEGIN{} {} END{}'
# BEGIN{ } 行前处理,读取文件内容前执行,指令执行1次
# { } 逐行处理,读取文件过程中执行,指令执行n次
# END{ } 行后处理,读取文件结束后执行,指令执行1次

[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEGIN{name=""}{name=name"_"$1}END{print name}'
_root_bin_daemon_adm
[root@kvm ckh]# cat 1.txt | awk 'BEGIN{print NR}END{print NR}'
0
4


[root@kvm ckh]# echo | awk 'BEGIN{sum=0}{for(i=0;i<=100;i++)sum+=i}END{print sum}'
5050
上面的展开
awk 'BEGIN{
       sum=0
     }
     {for(i=0;i<=100;i++)
        sum+=i
     }
     END{
        print sum
     }'

# 此种情况,循环还可以写到 end 里
[root@kvm ckh]# echo | awk 'BEGIN{sum=0} END{for(i=0;i<=100;i++){sum+=i}print sum}'
5050
上面的展开
awk 'BEGIN{
       sum=0
     }
     END{
        for(i=0;i<=100;i++) {
            sum+=i
        }
        print sum
     }'

# 此种情况,循环还可以写到 end 里
[root@kvm ckh]# echo | awk 'BEGIN{sum=0;for(i=0;i<=100;i++)sum+=i}END{print sum}'
5050

# 总结:不遍历文件的情况下,等同于,正常的函数
# awk 'BEGIN{
    1
    2
    3
    ...
} {
    1
    2
    3
    ...
} END{
    1
    2
    3
    ...
}'

# 一个 {} 里面可以写完一切,但是要写到一行,中间用;分割
[root@kvm ckh]# echo | awk '{sum=0;for(i=0;i<=100;i++)sum+=i;print sum}'
5050

# 有BEGIN 可以不用 echo | 了
[root@kvm ckh]# awk 'BEGIN{A=24;print A*2}'
48
[root@kvm ckh]#
[root@kvm ckh]# awk '{A=24;print A*2}'

48

48

48
^C
[root@kvm ckh]# awk '{sum=0;for(i=0;i<=100;i++)sum+=i;print sum}'

5050

5050
^C
[root@kvm ckh]#
[root@kvm ckh]# awk 'BEGIN{sum=0;for(i=0;i<=100;i++)sum+=i;print sum}'
5050
7. 计算
[root@kvm ckh]# awk 'BEGIN{print 1.2+2.5}'
3.7
[root@kvm ckh]# awk 'BEGIN{print 1.3*2.5}'
3.25
8.统计某个字符串出现的次数
[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEING{sum=0}/nologin/{sum++}END{print sum}'
3
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEING{sum=0} /nologin/{sum++} END{print sum}'
9. ~ 匹配 !~ 不匹配
[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEING{sum=0} /nologin/{sum++} END{print sum}'
3
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEGIN{sum=0}$7~"login"{sum++}END{print sum}'
3
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEGIN{sum=0}$7~"login$"{sum++}END{print sum}'
3
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEGIN{sum=0}$7!~"login$"{sum++}END{print sum}'
1
[root@kvm ckh]# cat 1.txt | awk -F":" 'BEGIN{sum=0}$7=="/sbin/nologin"{sum++}END{print sum}'
3
10. 数字相等判断
[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt | awk -F":" '$3>1{print}'
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

# 与行数比较
[root@kvm ckh]# awk  -F":" 'NR>=2{print}' 1.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

# 并且
[root@kvm ckh]# cat 1.txt | awk -F: '$3>1 && $3<3'
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@kvm ckh]# cat 1.txt | awk -F: '$3>1 && $3<3{print}'
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@kvm ckh]# cat 1.txt | awk -F: '$3>1 && $3<3{print $1 $2 $3}'
daemonx2

# 逻辑测试条件
awk -F: '$3>10 && $3<20'        /etc/passwd  ---> 输出UID大于10小于20的行
awk -F: '$3>1000 || $3<10'      /etc/passwd  ---> UID大于1000或小于10

# 数学运算 + - * / % ++  ——  +=  -=  *=  /=
awk 'NR%2==1{print}'         1.txt  ---> 输出奇数行
awk 'BEGIN{x++;print x}'            ---> 初始值为0,自加1,输出
awk 'BEGIN{x=8;x+=2;print x}'       ---> 10
awk 'BEGIN{print 23%8}'             ---> 7
seq 200 | awk 'BEGIN{i=0}($0%3==0)&&($o%13==0){i++} END{print i}' -->能被3和

# 整除
seq 100 | awk '$i%7==0||$i~/7/'     ---> 7的倍数或包含7的数
awk -F: '{print tolower($1)}' /etc/passwd  --->大写转小写(toupper 大写)
awk -F: '{print length($1)}'  /etc/passwd  --->$1的长度

11. 高级用法
# awk 中定义数组
# 数组的语法格式
# 数组是一个可以存储多个值的变量,具体使用的格式如下:
# 定义数组的格式:数组名[下标]=元素值
# 调用数组的格式:数组名[下标]
# 遍历数组的用法:for(变量 in 数组名){print 数组名[变量]}。
awk 'BEGIN{a[0]=11;a[1]=88;print a[1],a[0]}'   ---> 赋值数组并输出
awk 'BEGIN{a[0]++;print a[0]}'                 ---> 首项默认0,自加为1
awk 'BEGIN{a[0]=0;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}'
    0 0          rem:for (in i in a) 指的是下标
    1 11         rem:i时下标号
    2 22         rem:a 默认时下标
awk 'BEGIN{a["hehe"]=11;print a["hehe"]}'      ---> 下标是字符串

# 指定宽度对齐
# 说明:
#     %-30s表示输出字符串,宽度30位,左对齐.
#     %-15s用来指定第二列的,左对齐,宽度15.
#     两个百分号之间可以没有空格.
#     使用\n对每一行的输出加上换行符

[root@kvm ckh]# cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@kvm ckh]#
[root@kvm ckh]# awk -F: '{print "user:" $1"\t\tuid:" $3}' 1.txt
user:root               uid:0
user:bin                uid:1
user:daemon             uid:2
user:adm                uid:3
[root@kvm ckh]#
[root@kvm ckh]# awk -F: '{print "user:" $1"\t\tuid:" $3}' 1.txt | awk '{printf "%-30s%-15s\n",$1,$2}' | head -5
user:root                     uid:0
user:bin                      uid:1
user:daemon                   uid:2
user:adm                      uid:3

# if else
awk 'BEGIN{a="100testaaa";if(a~/100/&&a~/test/){print "包含100和test"}else{print "不包含100和test"}}'
包含100和test

# 字符串替换 gsub( Ere, Repl, [ In ] )  || sub( Ere, Repl, [ In ] )
[root@kvm ckh]# awk 'BEGIN{info="My phone number is 131-5209-8678";gsub(/[0-9]{4,}/,"xxxx",info);print tolower(info)}'
my phone number is 131-xxxx-xxxx

# 字符串查找 存在则返回首次出现的位置,不存在返回0 index( String1, String2 )
[root@kvm ckh]# echo "bb aabccbb" | awk '{print index($2,$1)}'
6
[root@kvm ckh]# echo "ff aabccbb" | awk '{print index($2,$1)}'
0

# 大小写转换 及 字符串长度
[root@kvm ckh]# echo "aa BBCC" | awk '{print toupper($1),tolower($2),length($2)}'
AA bbcc 4

# 字符串截取 substr( String, M, [ N ] )
[root@kvm ckh]# awk 'BEGIN{info="123456789";print substr(info,4,5);}'
45678

# 字符串匹配 match( String, Ere )
[root@kvm ckh]# awk 'BEGIN{info="aaa456bbb";print match(info,/[0-9]+/)}'
4
[root@kvm ckh]# awk 'BEGIN{info="aaabbb";print match(info,/[0-9]+/)}'
0
[root@kvm ckh]#
[root@kvm ckh]# awk 'BEGIN{info="aaaa456bbb";print match(info,/[0-9]+/)}'
5
[root@kvm ckh]# awk 'BEGIN{info="aaa456bbb";print match(info,/[0-9]+/)?"ok":"not found";}'
ok
[root@kvm ckh]#
[root@kvm ckh]# awk 'BEGIN{info="aaabbb";print match(info,/[0-9]+/)?"ok":"not found";}'
not found

# 字符串分割 split( String, A, [Ere] )
[root@kvm ckh]# awk 'BEGIN{info="aaa#456#bbb";split(info,res,"#");print length(res);for(i in res){print i,res[i]}}'
3
1 aaa
2 456
3 bbb