awk基础

和虚拟机无关,在任何虚拟机上操作都可以的

[root@centos77 ~]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.137.77  netmask 255.255.255.0  broadcast 192.168.137.255
        inet6 fe80::5de5:1874:5e74:be1d  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:63:99:29  txqueuelen 1000  (Ethernet)
        RX packets 2088  bytes 230605 (225.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1314  bytes 185011 (180.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

一awk介绍

awk是Linux实际工作中重要强大的工具,相当于一门语言,使得工作得心应手。

awk由来:是Aho, Weinberger, Kernighan这3个人一起发布的软件,取其名字首字母。

awk作用:做报表的报告生成器,格式化文本输出,用来处理数据和生成报告。

处理的数据可以是一个或多个文件,它是Linux系统最强大的文本处理工具

awk的版本:New awk(nawk),GNU awk( gawk)

Linux系统默认使用的是基于GNU项目开发出来的gawk

[root@centos77 ~]# awk 
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:        GNU long options: (standard)
    -f progfile        --file=progfile
    -F fs            --field-separator=fs
    -v var=val        --assign=var=val
Short options:        GNU long options: (extensions)
    -b            --characters-as-bytes
    -c            --traditional
    -C            --copyright
    -d[file]        --dump-variables[=file]
    -e 'program-text'    --source='program-text'
    -E file            --exec=file
    -g            --gen-pot
    -h            --help
    -L [fatal]        --lint[=fatal]
    -n            --non-decimal-data
    -N            --use-lc-numeric
    -O            --optimize
    -p[file]        --profile[=file]
    -P            --posix
    -r            --re-interval
    -S            --sandbox
    -t            --lint-old
    -V            --version

To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.

Examples:
    gawk '{ sum += $1 }; END { print sum }' file
    gawk -F: '{ print $1 }' /etc/passwd
[root@centos77 ~]# which   awk 
/usr/bin/awk
[root@centos77 ~]# ll  /usr/bin/awk
lrwxrwxrwx. 1 root root 4 Jan 24 19:05 /usr/bin/awk -> gawk

注意如果学了bash之后学这个就比较快了。因为语言是相通的

gawk:模式扫描和处理语言

GAWK(1)                                                                             Utility Commands                                                                            GAWK(1)

NAME
       gawk - pattern scanning and processing language

二awk的基本用法

(一)基本格式


awk [options]     ‘program’ var=value file… 
awk [options]    -f    programfile var=value file…

注意文件就是参数

awk [options] 'BEGIN{ action;… } pattern{ action;… } END{action;… }' file ...

awk [参数] 条件(动作)文件

注意这里的模式pattern就相当于是条件。

在awk命令及后面的选项和文件里,每个元素之间都至少要有一个空格。



   

基本格式:awk [options] 'program' file…

program由pattern{action statements;..}组成


program、pattern、action:

program左右两边通常要加单引号或双引号

pattern部分决定动作语句何时触发及触发事件BEGIN,END
action statements对数据进行处理,放在{}内指明
命令有print, printf,后者功能更强大。

比如字段与字段有多宽,小数点可以有几位。

printf也是linux里面的命令,和echo的选项是相似的。

[root@centos77 ~]# printf
printf: usage: printf [-v var] format [arguments]
[root@centos77 ~]# type  printf
printf is a shell builtin

基本格式:awk [options] 'BEGIN{ action;… } pattern{ action;… } END{action;… }' file ...
awk [options]   'BEGIN{ action;… }

表示还没有读取文件就做的事,比如把表头打出来      

pattern   { action;… }

表示的是对每一行进行处理。

END{  action;… }' file ... 就是把所有的行都读完了做一下收尾性的工作,比如做统计,汇总等等。

awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成。



(二)分割符、域和记录


 awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。

$0为所有域,也就是整行。

注意和shell中变量$符含义不同,在bash里面$0表示的程序名和路径。

文件的每一行称为记录,但是并不是只有一行就是记录。

比如a:bb;ccc:dddd;  这一行里面a:bb;就是一条记录了,a:bb是用冒号隔开的,就是两个字段。

省略action,则默认执行 print $0 的操作,也就是把整行打印出来。

三awk的工作原理

文本文件有很多行,awk每次会读取一行,读入到awk的内存空间。

处理了一行就会自动读取下一行。

会把定义的分隔符切割成字段,可以使用-F 指明输入时用到的字段分隔符。

和cut类似,cut  -d:。

切割成字段之后使用$1,$2...表示每个字段,取其中第几列就很简单。

awk具有循环功能是为了对字段进行轮流处理。

默认情况下读取每行,但是可以设置条件进行过滤,只处理符合条件的行。

第一步:执行BEGIN{action;… }语句块中的语句,没有读取文件行之前的操作。


第二步:从文件或标准输入(stdin)读取一行,标准输入会涉及到管道或者命令的执行结果。

然后执行pattern{  action;… }语句块,它逐行扫描文件,

从第一行到最后一行重复这个过程,直到文件全部被读取完毕。

如果符合pattern的定义就执行里面的动作。

第三步:当读至输入流末尾时,执行END{action;…}语句块。


BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,

比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。


END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,

也是一个可选语句块。


pattern语句块中的通用命令是最重要的部分,也是可选的。

如果没有提供pattern语句块,则默认执行{ print } ,即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

四awk的print格式

awk的print格式: print     item1, item2, ...


(一)要点


(1)使用逗号作为分隔符


(2)输出的各item可以字符串、数值、当前记录的字段、变量、awk表达式



(3)省略item,相当于print $0,打印每一行

五awk的内置变量

awk的变量类型主要是内置变量,比如$0,$1.....,自定义变量

1FS:是field  split的简写,域,字段,列column,属性。

作用是输入文件的字段分隔符,默认为空白字符。

与之相对应的是行,记录,也就是record。

execl表格和数据库里面的表都是横行纵列。

 -v表示的是对变量进行赋值。

(一)FS:设置输入字段分隔符,和命令行-F等价,默认为空白字符

[root@centos77 ~]# awk  -v   FS=':'   '{print $1,$3}'    /app/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
wang 1000
mysql 27
apache 48

使用FS比-F更强大的功能在于可以调用变量,这样会更加的灵活

[root@centos77 ~]# awk -v FS=':' '{print $1,FS,$3}'    /app/passwd
root : 0
bin : 1
daemon : 2
adm : 3
lp : 4
sync : 5
shutdown : 6
halt : 7
mail : 8
operator : 11
games : 12
ftp : 14
nobody : 99
systemd-network : 192
dbus : 81
polkitd : 999
sshd : 74
postfix : 89
wang : 1000
mysql : 27
apache : 48

以FS的值作为分隔符

[root@centos77 ~]# awk  -v    FS=":"   '{print $1FS$3}'    /app/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
operator:11
games:12
ftp:14
nobody:99
systemd-network:192
dbus:81
polkitd:999
sshd:74
postfix:89
wang:1000
mysql:27
apache:48

使用FS变量可以调用bash里面的变量

[root@centos77 ~]# sep=":";awk  -v  FS="$sep"      '{print $1,FS,$3}'    /app/passwd
root : 0
bin : 1
daemon : 2
adm : 3
lp : 4
sync : 5
shutdown : 6
halt : 7
mail : 8
operator : 11
games : 12
ftp : 14
nobody : 99
systemd-network : 192
dbus : 81
polkitd : 999
sshd : 74
postfix : 89
wang : 1000
mysql : 27
apache : 48

-F指定多分割符

以取IP地址为例

[root@centos72 ~]# ifconfig  ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.137.72  netmask 255.255.255.0  broadcast 192.168.137.255
        inet6 fe80::b029:2522:876f:5456  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:fc:69:f8  txqueuelen 1000  (Ethernet)
        RX packets 770189  bytes 48135532 (45.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1458827  bytes 3300993378 (3.0 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

中括号里面空几格和实际情况有关,分割符最好是使用双引号,以示区别

NR==2{print $2}表示第2行,第2个字段,分隔符为第1个分隔符(inet )

[root@centos72 ~]# ifconfig  ens33  |  awk  -F  "(inet )|( netmask)"   'NR==2{print  $2}'
192.168.137.72 
[root@centos72 ~]# ifconfig  ens33  |  awk  -F  "( inet )|( netmask )"   'NR==2{print  $2}'
192.168.137.72 
[root@centos72 ~]# ifconfig  ens33  |  awk  -F  "(inet)|( netmask)"   'NR==2{print  $2}'
 192.168.137.72 

分割符如果不加引号就会报错

[root@centos72 ~]#  ifconfig  ens33  |  awk  -F  ( inet )|( netmask )   'NR==2{print  $2}'
-bash: syntax error near unexpected token `('

法2:

IP地址的左边是空格,可以用空格作为分隔符;右边是空格,可以用空格作为分隔符
行的最左边是多个空格那么就结合正则表达式的加号+,表示重复前面一个字符一次或一次以上。
所以表示一个或多个空格作为分隔符

[root@centos72 ~]# ifconfig  ens33  |  awk  -F  "[ ]+"  'NR==2{print  $3}'
192.168.137.72
[root@centos72 ~]#  ifconfig  ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.137.72  netmask 255.255.255.0  broadcast 192.168.137.255
        inet6 fe80::b029:2522:876f:5456  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:fc:69:f8  txqueuelen 1000  (Ethernet)
        RX packets 770482  bytes 48162199 (45.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1459030  bytes 3301018060 (3.0 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

分割符如果不加引号就会报错

[root@centos72 ~]#  ifconfig  ens33  |  awk  -F  [ :]+  'NR==2{print  $3}'
awk: cmd. line:1: :]+
awk: cmd. line:1: ^ syntax error
[root@centos72 ~]#  ifconfig  ens33  |  awk  -F  '[ :]+'  'NR==2{print  $3}'
192.168.137.72

(二)OFS:输出字段分隔符,默认为空白字符

输入分隔符是对文件的判断,这样才知道是$1,$2,起到了定位的作用。

[root@centos77 ~]# awk  -v    FS=":"    -v  OFS="+++"    '{print $1,$3}'    /app/passwd
root+++0
bin+++1
daemon+++2
adm+++3
lp+++4
sync+++5
shutdown+++6
halt+++7
mail+++8
operator+++11
games+++12
ftp+++14
nobody+++99
systemd-network+++192
dbus+++81
polkitd+++999
sshd+++74
postfix+++89
wang+++1000
mysql+++27
apache+++48
[root@centos77 ~]# awk     -v  OFS="+++"    '{print $1,$3}'    /app/passwd
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+++
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin+++
sync:x:5:0:sync:/sbin:/bin/sync+++
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown+++
halt:x:7:0:halt:/sbin:/sbin/halt+++
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin+++
operator:x:11:0:operator:/root:/sbin/nologin+++
games:x:12:100:games:/usr/games:/sbin/nologin+++
ftp:x:14:50:FTP+++
nobody:x:99:99:Nobody:/:/sbin/nologin+++
systemd-network:x:192:192:systemd+++Management:/:/sbin/nologin
dbus:x:81:81:System+++bus:/:/sbin/nologin
polkitd:x:999:998:User+++polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated+++
postfix:x:89:89::/var/spool/postfix:/sbin/nologin+++
wang:x:1000:1000:wang:/home/wang:/bin/bash+++
mysql:x:27:27:MariaDB+++
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin+++



(三)RS:输入记录分隔符,指定输入时的换行符

回车换行作为行的分隔符。

下面可以认为是两行。

mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

但是也可以设置为以;作为行的分隔符。

所以下面可以认为是两行。

mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin;apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

取/etc/passwd的最后一行说明,把所有的冒号修改成分号。

巧记比如以分号作为记录的分隔符。那么记录的数量就是分号的数量+1

apache;x;48;48;Apache;/usr/share/httpd;/sbin/nologin
apache;x;48;48;Apache;/usr/
share/httpd;/sbin/nologin
 
apache;x;48;48;Apache;/usr/
share/httpd;/sbin/
nologin

上面都是6个分号,那么就是7条记录了。


设置分号作为输入记录的分隔符

要打印字段,默认是空白符作为分隔符,回车也是空白符。

[root@centos77 ~]# cat  RS1.txt 
apache;x;48;48;Apache;/usr/
share/httpd;/sbin/
nologin


[root@centos77 ~]# awk  -v   RS=";"   '{print $1}'   RS1.txt
apache
x
48
48
Apache
/usr/
/sbin/
[root@centos77 ~]# awk  -v   RS=";"   '{print $2}'   RS1.txt





share/httpd
nologin
[root@centos77 ~]# awk  -v   RS=";"   '{print $3}'   RS1.txt

设置空格作为分隔符。

注意同一列不同行,比如第1行和第2行,就是空了两格。

因为没有定义字段的分隔符,回车换行也是空白分隔符。

[root@centos77 ~]# vim  RS2.txt
[root@centos77 ~]# cat  RS2.txt 
a b
aa bb
aaa bb
aaa
[root@centos77 ~]# awk  -v   RS=" "  '{print   $1,$2}'  RS2.txt
a 
b aa
bb aaa
bb aaa

(四)ORS:输出记录分隔符

输出时用指定符号代替回车换行符。

[root@centos77 ~]# awk -v RS=' ' -v ORS='###'  '{print }'   RS2.txt
a###b
aa###bb
aaa###bb
aaa
[root@centos77 ~]# awk -v RS=" "   -v ORS='###'  '{print }'   RS2.txt
a###b
aa###bb
aaa###bb
aaa

(五)NF:显示一行里面的字段数量

[root@centos77 ~]# awk  -F: '{print NF}'   /etc/fstab
0
1
1
1
1
1
1
1
1
1
1
1
1
[root@centos77 ~]# cat  /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Thu Jan 24 19:04:38 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
/dev/cdrom   /mnt   iso9660   defaults  0 0
[root@centos72 ~]# awk  -F":" '{print NF}'   /etc/fstab
0
1
1
3
1
1
1
1
1
1
1
1
[root@centos72 ~]# awk  -F":" '{print NF}'   /etc/fstab  |  wc
     12      12      24
[root@centos72 ~]# awk  -F: '{print NF}'   /etc/fstab  
0
1
1
3
1
1
1
1
1
1
1
1
[root@centos72 ~]# awk  -F: '{print NF}'   /etc/fstab  |  wc
     12      12      24
[root@centos77 ~]# awk  -F:  '{print NF}'   /etc/passwd
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7

(六)$NF显示一行最后一个字段

[root@centos77 ~]# awk  -F:  '{print $NF}'   /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
/sbin/nologin
/sbin/nologin
[root@centos77 ~]# cat  /etc/passwd
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
wang:x:1000:1000:wang:/home/wang:/bin/bash
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

注意显示倒数第2就要在$后面加上中括号

[root@centos77 ~]# awk  -F:  '{print $NF-1}'   /etc/passwd
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1

 正确的写法

[root@centos77 ~]# awk  -F:  '{print $(NF-1)}'   /etc/passwd
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
/var/spool/mail
/root
/usr/games
/var/ftp
/
/
/
/
/var/empty/sshd
/var/spool/postfix
/home/wang
/var/lib/mysql
/usr/share/httpd
[root@centos77 ~]# ss  -nt
State      Recv-Q Send-Q                                                 Local Address:Port                                                                Peer Address:Port              
ESTAB      0      52                                                    192.168.137.77:22                                                                192.168.137.34:61644
[root@centos77 ~]# ss  -nt   |   awk     -F:  '{print $NF}'
Port              
61644              
[root@centos77 ~]# ss  -nt   |   awk       '{print $NF}'
Address:Port
192.168.137.34:61644
[root@centos77 ~]# ss  -nt   |   awk       '{print $NF}'   |   awk  -F: '{print $NF}'
Port
61644
[root@centos77 ~]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2       51175000 1421948  49753052   3% /
devtmpfs          487964       0    487964   0% /dev
tmpfs             498988       0    498988   0% /dev/shm
tmpfs             498988    7832    491156   2% /run
tmpfs             498988       0    498988   0% /sys/fs/cgroup
/dev/sr0         4364408 4364408         0 100% /mnt
/dev/sda3       20961280   32948  20928332   1% /app
/dev/sda1        1038336  126596    911740  13% /boot
tmpfs              99800       0     99800   0% /run/user/0
[root@centos77 ~]# df  |  grep   /dev/sd
/dev/sda2       51175000 1421948  49753052   3% /
/dev/sda3       20961280   32948  20928332   1% /app
/dev/sda1        1038336  126596    911740  13% /boot
[root@centos77 ~]# df  |  grep   /dev/sd   |   awk   '{print  $(NF-1) }'
3%
1%
13%

[root@centos77 ~]# df  |  grep   /dev/sd   |   awk   '{print  $(NF-1) }'   |    awk  -F% '{print $1}'
3
1
13

使用cut也可以显示

[root@centos72 ~]# cut -d:   -f7 /etc/passwd  | head
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin
[root@centos72 ~]# cat   /etc/passwd  | head
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

(七)NR:记录号,默认情况是行号

注意空行也算行号

[root@centos77 ~]# awk '{print NR}' /etc/fstab 
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@centos77 ~]# cat  /etc/fstab   -n
     1    
     2    #
     3    # /etc/fstab
     4    # Created by anaconda on Thu Jan 24 19:04:38 2019
     5    #
     6    # Accessible filesystems, by reference, are maintained under '/dev/disk'
     7    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
     8    #
     9    UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
    10    UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
    11    UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
    12    UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
    13    /dev/cdrom   /mnt   iso9660   defaults  0 0

 

 

 给文件每行内容加上行号

[root@centos77 ~]# awk '{print NR,$0}' /etc/fstab 
1 
2 #
3 # /etc/fstab
4 # Created by anaconda on Thu Jan 24 19:04:38 2019
5 #
6 # Accessible filesystems, by reference, are maintained under '/dev/disk'
7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 #
9 UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
10 UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
11 UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
12 UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
13 /dev/cdrom   /mnt   iso9660   defaults  0 0

如果是在命令行输入两个文件,那么就会按照顺序显示,整合成一个文件的编号

[root@centos77 ~]# awk '{print NR,$0}' /etc/fstab   /etc/issue
1 
2 #
3 # /etc/fstab
4 # Created by anaconda on Thu Jan 24 19:04:38 2019
5 #
6 # Accessible filesystems, by reference, are maintained under '/dev/disk'
7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 #
9 UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
10 UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
11 UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
12 UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
13 /dev/cdrom   /mnt   iso9660   defaults  0 0
14 S
15 Kernel 
 on an m
16 
[root@centos77 ~]# cat /etc/issue
S
Kernel 
 on an m

显示文件第几行

和shell脚本一样,==表示判断是否相等

[root@centos72 ~]# awk  'NR==2'  /etc/issue
Kernel 
 on an m
[root@centos72 ~]# cat  -n  /etc/issue
     1    S
     2    Kernel 
 on an m
     3    

显示文件一部分内容,从第几行到第几行

[root@centos72 ~]# awk  'NR==1,NR==5'  /etc/passwd
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@centos72 ~]# head  -n5  /etc/passwd
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

显示文件第几行到第几行,并且显示行号

[root@centos72 ~]# awk  'NR==1,NR==7  {print NR,$0}'   /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
[root@centos72 ~]# head  -n  7  /etc/passwd  |  cat  -n
     1    root:x:0:0:root:/root:/bin/bash
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6    sync:x:5:0:sync:/sbin:/bin/sync
     7    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

(八)FNR:各文件分别计数,记录号

 

每个文件都有独立的编号,和七相反

[root@centos77 ~]# awk '{print FNR,$0}' /etc/fstab   /etc/issue
1 
2 #
3 # /etc/fstab
4 # Created by anaconda on Thu Jan 24 19:04:38 2019
5 #
6 # Accessible filesystems, by reference, are maintained under '/dev/disk'
7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 #
9 UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
10 UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
11 UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
12 UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
13 /dev/cdrom   /mnt   iso9660   defaults  0 0
1 S
2 Kernel 
 on an m
3 

(九)FILENAME:显示当前文件名,awk浏览的文件名

后面的文件名相当于参数,文件内容被替换为对应的文件名

[root@centos77 ~]# awk '{print FILENAME}'   /etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
[root@centos77 ~]# awk '{print FILENAME,$0}'   /etc/fstab
/etc/fstab 
/etc/fstab #
/etc/fstab # /etc/fstab
/etc/fstab # Created by anaconda on Thu Jan 24 19:04:38 2019
/etc/fstab #
/etc/fstab # Accessible filesystems, by reference, are maintained under '/dev/disk'
/etc/fstab # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
/etc/fstab #
/etc/fstab UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
/etc/fstab UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
/etc/fstab UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
/etc/fstab UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
/etc/fstab /dev/cdrom   /mnt   iso9660   defaults  0 0
[root@centos77 ~]# awk '{print FNR,FILENAME,$0}'   /etc/fstab
1 /etc/fstab 
2 /etc/fstab #
3 /etc/fstab # /etc/fstab
4 /etc/fstab # Created by anaconda on Thu Jan 24 19:04:38 2019
5 /etc/fstab #
6 /etc/fstab # Accessible filesystems, by reference, are maintained under '/dev/disk'
7 /etc/fstab # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 /etc/fstab #
9 /etc/fstab UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
10 /etc/fstab UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
11 /etc/fstab UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
12 /etc/fstab UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
13 /etc/fstab /dev/cdrom   /mnt   iso9660   defaults  0 0

(十)ARGC:命令行参数个数

ARG表示的是argument参数

这里的参数指的是是命令awk,后面的文件名 /etc/fstab 、/etc/issue

分别表示参数1、参数2、参数3

这种玩法是比较新鲜的,在三剑客里面的其他两个并没有这种功能

可能和林纳斯.托瓦茨一样,只是为了好玩

[root@centos77 ~]# awk '{print ARGC}'    /etc/fstab   /etc/issue
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
[root@centos72 ~]# awk '{print ARGC}'    /etc/issue
2
2
2
[root@centos72 ~]# cat  /etc/issue
S
Kernel 
 on an m
[root@centos72 ~]# awk '{print ARGC}'    /etc/issue  /etc/passwd  /etc/fstab  | wc
     65      65     130
[root@centos72 ~]# awk '{print ARGC}'    /etc/issue  /etc/passwd  /etc/fstab  |  head
4
4
4
4
4
4
4
4
4
4
[root@centos72 ~]# awk '{print ARGC}'    /etc/issue  /etc/passwd  /etc/fstab  |  tail
4
4
4
4
4
4
4
4
4
4

 注意是文件名才可以,目录名会报错

[root@centos72 ~]# awk '{print ARGC}'    /etc
awk: warning: command line argument `/etc' is a directory: skipped
[root@centos72 ~]# awk '{print ARGC}'    /etc/
awk: warning: command line argument `/etc/' is a directory: skipped
[root@centos72 ~]# ll  -d  /etc/
drwxr-xr-x. 75 root root 8192 Jul 15 16:56 /etc/

(十一)ARGV:数组,保存的是命令行所给定的各参数

显示了命令行的参数1,也就是命令awk

[root@centos77 ~]# awk    '{print ARGV[0]}'    /etc/fstab   /etc/issue
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk

 显示了命令行的参数2

[root@centos77 ~]# awk    '{print ARGV[1]}'    /etc/fstab   /etc/issue
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab

 显示了命令行的参数3

[root@centos77 ~]# awk    '{print ARGV[2]}'    /etc/fstab   /etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue

六awk的自定义变量

注意区分字符大小写


(一) -v     var=value

[root@centos77 ~]#    awk -v       test='hello gawk'    -F:   '{print $1,test,$2}'      /etc/passwd
root hello gawk x
bin hello gawk x
daemon hello gawk x
adm hello gawk x
lp hello gawk x
sync hello gawk x
shutdown hello gawk x
halt hello gawk x
mail hello gawk x
operator hello gawk x
games hello gawk x
ftp hello gawk x
nobody hello gawk x
systemd-network hello gawk x
dbus hello gawk x
polkitd hello gawk x
sshd hello gawk x
postfix hello gawk x
wang hello gawk x
mysql hello gawk x
apache hello gawk x
[root@centos72 ~]#   awk -v       test='hello gawk'       '{print $1,test,$2}'      /etc/issue
S hello gawk 
Kernel hello gawk 
 hello gawk 
[root@centos72 ~]# cat   /etc/issue
S
Kernel 
 on an m
[root@centos77 ~]#    awk -v       test='hello gawk'      '{print $1,test,$2}'      /etc/passwd
root:x:0:0:root:/root:/bin/bash hello gawk 
bin:x:1:1:bin:/bin:/sbin/nologin hello gawk 
daemon:x:2:2:daemon:/sbin:/sbin/nologin hello gawk 
adm:x:3:4:adm:/var/adm:/sbin/nologin hello gawk 
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin hello gawk 
sync:x:5:0:sync:/sbin:/bin/sync hello gawk 
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown hello gawk 
halt:x:7:0:halt:/sbin:/sbin/halt hello gawk 
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin hello gawk 
operator:x:11:0:operator:/root:/sbin/nologin hello gawk 
games:x:12:100:games:/usr/games:/sbin/nologin hello gawk 
ftp:x:14:50:FTP hello gawk User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin hello gawk 
systemd-network:x:192:192:systemd hello gawk Network
dbus:x:81:81:System hello gawk message
polkitd:x:999:998:User hello gawk for
sshd:x:74:74:Privilege-separated hello gawk SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin hello gawk 
wang:x:1000:1000:wang:/home/wang:/bin/bash hello gawk 
mysql:x:27:27:MariaDB hello gawk Server:/var/lib/mysql:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin hello gawk 

/etc/issue作为测试效果的文件会比较好,因为里面的文件内容几乎不修改

[root@centos72 ~]#  awk -v       test='hello gawk'      '{print $1,test,$2}'  /etc/issue
S hello gawk 
Kernel hello gawk 
 hello gawk 
[root@centos77 ~]#    awk -v     user="username"    -v   uid="uid"   -F:    '{print   user":"$1"                     "uid":"$3}'      /etc/passwd
username:root                     uid:0
username:bin                     uid:1
username:daemon                     uid:2
username:adm                     uid:3
username:lp                     uid:4
username:sync                     uid:5
username:shutdown                     uid:6
username:halt                     uid:7
username:mail                     uid:8
username:operator                     uid:11
username:games                     uid:12
username:ftp                     uid:14
username:nobody                     uid:99
username:systemd-network                     uid:192
username:dbus                     uid:81
username:polkitd                     uid:999
username:sshd                     uid:74
username:postfix                     uid:89
username:wang                     uid:1000
username:mysql                     uid:27
username:apache                     uid:48
[root@centos77 ~]#    awk -v     user="username"    -v   uid="uid"   -F:    '{print   user":"$1"          
           "uid    ":"$3}'      /etc/passwd
username:root          
           uid:0
username:bin          
           uid:1
username:daemon          
           uid:2
username:adm          
           uid:3
username:lp          
           uid:4
username:sync          
           uid:5
username:shutdown          
           uid:6
username:halt          
           uid:7
username:mail          
           uid:8
username:operator          
           uid:11
username:games          
           uid:12
username:ftp          
           uid:14
username:nobody          
           uid:99
username:systemd-network          
           uid:192
username:dbus          
           uid:81
username:polkitd          
           uid:999
username:sshd          
           uid:74
username:postfix          
           uid:89
username:wang          
           uid:1000
username:mysql          
           uid:27
username:apache          
           uid:48

(二)在program中直接定义

这样写的缺点是不能调用bash的变量了。

[root@centos77 ~]#    awk       -v   uid="uid"   -F:    '{    user="username";   print   user":"$1"          
           "uid    ":"$3}'     
/etc/passwd username:root uid:0 username:bin uid:1 username:daemon uid:2 username:adm uid:3 username:lp uid:4 username:sync uid:5 username:shutdown uid:6 username:halt uid:7 username:mail uid:8 username:operator uid:11 username:games uid:12 username:ftp uid:14 username:nobody uid:99 username:systemd-network uid:192 username:dbus uid:81 username:polkitd uid:999 username:sshd uid:74 username:postfix uid:89 username:wang uid:1000 username:mysql uid:27 username:apache uid:48

下面使用到了bash变量u

[root@centos77 ~]# u="user";awk  -v   username="$u"   -F:   '{uid="uid";print  username":"$1"
"uid":"$3    }'   /etc/passwd
user:root
uid:0
user:bin
uid:1
user:daemon
uid:2
user:adm
uid:3
user:sync
uid:5
user:shutdown
uid:6
user:halt
uid:7
user:mail
uid:8
user:operator
uid:11
user:games
uid:12
user:ftp
uid:14
user:nobody
uid:99
user:systemd-network
uid:192
user:dbus
uid:81
user:polkitd
uid:999
user:sshd
uid:74
user:postfix
uid:89
user:wang
uid:1000
user:mysql
uid:27
user:apache
uid:48

先使用变量再对变量进行定义显示的结果有误

注意变量要先定义后使用。

所有的语言都是这样的。

[root@centos77 ~]# awk      -F:   '{print  username":"$1"
"uid":"$3;username="user";uid="uid"    }'   /etc/passwd
:root
:0
user:bin
uid:1
user:daemon
uid:2
user:adm
uid:3
user:lp
uid:4
user:sync
uid:5
user:shutdown
uid:6
user:halt
uid:7
user:mail
uid:8
user:operator
uid:11
user:games
uid:12
user:ftp
uid:14
user:nobody
uid:99
user:systemd-network
uid:192
user:dbus
uid:81
user:polkitd
uid:999
user:sshd
uid:74
user:postfix
uid:89
user:wang
uid:1000
user:mysql
uid:27
user:apache
uid:48

定义了变量之后会存储到内存里面的。

可以把经常写的awk命令写入到文件里面,这样方便调用。

[root@centos77 ~]# awk   -F:  -f    awkscript   /etc/passwd
username:root uid: 0
username:bin uid: 1
username:daemon uid: 2
username:adm uid: 3
username:lp uid: 4
username:sync uid: 5
username:shutdown uid: 6
username:halt uid: 7
username:mail uid: 8
username:operator uid: 11
username:games uid: 12
username:ftp uid: 14
username:nobody uid: 99
username:systemd-network uid: 192
username:dbus uid: 81
username:polkitd uid: 999
username:sshd uid: 74
username:postfix uid: 89
username:wang uid: 1000
username:mysql uid: 27
username:apache uid: 48
[root@centos77 ~]# cat  awkscript 
{user="username";uid="uid";print user":"$1,uid":",$3} 

七awk示例

(一)最简打印awk      '{print "hello,awk"}'    文件名

使用了基本格式:awk [options] 'program' file…

其中涉及到了action statements对数据进行处理,放在{}内指明,不涉及pattern

最外面的单引号引起来的是awk的程序代码,不涉及到模式就处理所有行。

涉及到了print格式: print item1, item2, ...

这里的action就是打印print这个动作

[root@centos77 app]# awk '{print "hello,awk"}'   /etc/fstab 
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk

不写模式就是处理所有的行

为什么打印这么多行,因为文件 /etc/fstab 有13行,所有的行都符合条件。

[root@centos77 app]# cat  /etc/fstab    -n
     1    
     2    #
     3    # /etc/fstab
     4    # Created by anaconda on Thu Jan 24 19:04:38 2019
     5    #
     6    # Accessible filesystems, by reference, are maintained under '/dev/disk'
     7    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
     8    #
     9    UUID=ac478774-8c43-475c-b9f5-b2f4de773371 /                       xfs     defaults        0 0
    10    UUID=20d0ead8-ff20-43a0-936d-2fe5f733a4cf /app                    xfs     defaults        0 0
    11    UUID=0ade30c3-a2e1-4150-88c4-29ad1acdb3c3 /boot                   xfs     defaults        0 0
    12    UUID=cde1f1c4-4f89-4618-80bb-30042181c194 swap                    swap    defaults        0 0
    13    /dev/cdrom   /mnt   iso9660   defaults  0 0
[root@centos77 app]# awk '{print "hello,awk"}'   /etc/fstab    |  wc
     13      13     130

后面不加文件名就是读入一行对这行进行处理,包括空行

[root@centos77 app]# awk '{print "hello,awk"}'   
a
hello,awk
dd
hello,awk
aadfff
hello,awk
afghre
hello,awk
ghjew
hello,awk

hello,awk
df
hello,awk

hello,awk

hello,awk

hello,awk

 回车之后的结果

[root@centos72 ~]# awk '{print "hello,awk"}'   

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

管道把前面的标准输入作为后面的标准输出

[root@centos77 app]# cat  /etc/fstab    |     awk '{print "hello,awk"}'  
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk

 输入重定向

[root@centos77 app]# awk '{print "hello,awk"}'    <    /etc/fstab    
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk

(二)指定分割符

指定分割符为冒号

[root@centos72 ~]# awk  -F:   '{print  $1}'  /etc/passwd  | head
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
[root@centos72 ~]# cat  /etc/passwd  | head
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

分隔符加不加引号都可以

[root@centos72 ~]# awk  -F":"   '{print  $1}'  /etc/passwd  | head
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
[root@centos72 ~]# awk  -F':'   '{print  $1}'  /etc/passwd  | head
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

打印整行

[root@centos72 ~]# awk  -F:   '{print  $0}'  /etc/passwd  | head
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

(三)对打印的items进行换行

默认是换成空行

[root@centos77 app]# awk '{print "hello,awk
"}'       /etc/fstab    
hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk

hello,awk
[root@centos72 ~]# awk '{print "hello,awk
"}'  /etc/issue
hello,awk

hello,awk

hello,awk

[root@centos72 ~]# awk '{print "hello,awk"}'  /etc/issue
hello,awk
hello,awk
hello,awk
[root@centos77 app]# awk '{print "hello,awk
hello world"}'       /etc/fstab    
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world
hello,awk
hello world

(四)进行数字运算

注意字符串都要使用双引号引起来,数字运算不加双引号。

[root@centos77 app]# awk '{print 2*3}'       /etc/fstab    
6
6
6
6
6
6
6
6
6
6
6
6
6
[root@centos77 app]# awk '{print "2*3"}'       /etc/fstab    
2*3
2*3
2*3
2*3
2*3
2*3
2*3
2*3
2*3
2*3
2*3
2*3
2*3

 但是可以加单引号

[root@centos72 ~]#  awk '{print '2*3'}'       /etc/fstab    
6
6
6
6
6
6
6
6
6
6
6
6
[root@centos77 app]# awk '{print 2^3}'       /etc/fstab    
8
8
8
8
8
8
8
8
8
8
8
8
8

(五)支持浮点数

下面进行除法运算的时候显示了小数点

[root@centos77 app]# awk '{print 2/3}'       /etc/fstab    
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667
0.666667

 

(六)对文件取出特定的字段

[root@centos77 ~]# cp  /etc/passwd   /app/
[root@centos77 ~]# cd   /app/
[root@centos77 app]# ls
passwd
[root@centos77 app]# cat  passwd 
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
wang:x:1000:1000:wang:/home/wang:/bin/bash
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

使用cut取特定的字段

用冒号作为分隔符,取出文件的第3个字段。

[root@centos77 ~]# cut -d: -f3   /etc/passwd
0
1
2
3
4
5
6
7
8
11
12
14
99
192
81
999
74
89
1000
27
48

使用awk取出特定的字段

awk   –F:   ‘{print   $1}’    /etc/passwd

-F:表示的分隔符是冒号。

-F和cut 里面的-d是等价的

$1表示的文件的第1个字段,相当于cut里面的-f1

这个就和国家的语言一样,表达上不一样,但是意思是一样的

[root@centos77 ~]# awk   -F:  '{print  $3}'    /app/passwd
0
1
2
3
4
5
6
7
8
11
12
14
99
192
81
999
74
89
1000
27
48
[root@centos77 ~]# awk   -F:  '{print  $1}'    /app/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
sshd
postfix
wang
mysql
apache

 

取出日志的第1个字段

[root@centos77 ~]# cat  /var/log/httpd/access_log   |  head 
192.168.137.34 - - [25/Jan/2019:14:35:37 +0800] "GET /info.php HTTP/1.1" 404 16 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
192.168.137.34 - - [25/Jan/2019:14:35:37 +0800] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
192.168.137.34 - - [25/Jan/2019:14:35:46 +0800] "GET / HTTP/1.1" 200 44251 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
192.168.137.34 - - [25/Jan/2019:14:35:47 +0800] "GET /index.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2524 "http://192.168.137.77/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
192.168.137.34 - - [25/Jan/2019:14:35:47 +0800] "GET /index.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 HTTP/1.1" 200 2146 "http://192.168.137.77/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
192.168.137.62 - - [25/Jan/2019:14:39:52 +0800] "GET /info.php HTTP/1.0" 404 16 "-" "ApacheBench/2.3"
192.168.137.62 - - [25/Jan/2019:14:39:52 +0800] "GET /info.php HTTP/1.0" 404 16 "-" "ApacheBench/2.3"
192.168.137.62 - - [25/Jan/2019:14:39:52 +0800] "GET /info.php HTTP/1.0" 404 16 "-" "ApacheBench/2.3"
192.168.137.62 - - [25/Jan/2019:14:39:52 +0800] "GET /info.php HTTP/1.0" 404 16 "-" "ApacheBench/2.3"
192.168.137.62 - - [25/Jan/2019:14:39:52 +0800] "GET /info.php HTTP/1.0" 404 16 "-" "ApacheBench/2.3"
[root@centos77 ~]# cat  /var/log/httpd/access_log    |   awk    '{print $1}'    |   head
192.168.137.34
192.168.137.34
192.168.137.34
192.168.137.34
192.168.137.34
192.168.137.62
192.168.137.62
192.168.137.62
192.168.137.62
192.168.137.62
[root@centos77 ~]#  awk    '{print $1}'   /var/log/httpd/access_log     |  head
192.168.137.34
192.168.137.34
192.168.137.34
192.168.137.34
192.168.137.34
192.168.137.62
192.168.137.62
192.168.137.62
192.168.137.62
192.168.137.62

 

使用awk同时取出多个字段

[root@centos77 ~]# awk   -F:  '{print  $1,$3,$5,$7}'    /app/passwd
root 0 root /bin/bash
bin 1 bin /sbin/nologin
daemon 2 daemon /sbin/nologin
adm 3 adm /sbin/nologin
lp 4 lp /sbin/nologin
sync 5 sync /bin/sync
shutdown 6 shutdown /sbin/shutdown
halt 7 halt /sbin/halt
mail 8 mail /sbin/nologin
operator 11 operator /sbin/nologin
games 12 games /sbin/nologin
ftp 14 FTP User /sbin/nologin
nobody 99 Nobody /sbin/nologin
systemd-network 192 systemd Network Management /sbin/nologin
dbus 81 System message bus /sbin/nologin
polkitd 999 User for polkitd /sbin/nologin
sshd 74 Privilege-separated SSH /sbin/nologin
postfix 89  /sbin/nologin
wang 1000 wang /bin/bash
mysql 27 MariaDB Server /sbin/nologin
apache 48 Apache /sbin/nologin



取出分区的利用率

awk是默认以空白符作为分隔符,使用时可不写分隔符

注意单引号和花括号程序之间的空格没有限制,也就是可以空格,也可以不空格,这个看个人的喜好了。

使用awk比tr会更方便。

[root@centos77 ~]# df  |  grep   /dev/sd |  awk  '{print  $5}'
3%
1%
13%
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  '{ print  $5 }'
3%
1%
13%
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $5 } '
3%
1%
13%

注意默认在程序里面加逗号就会在显示结果中空格,不加逗号可以在中间加上双引号

[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1,$5 } '
/dev/sda2 3%
/dev/sda3 1%
/dev/sda1 13%

在程序里面中间加上双引号显示结果也会空格

[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1" " $5 } '
/dev/sda2 3%
/dev/sda3 1%
/dev/sda1 13%
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1"  "$5 } '
/dev/sda2  3%
/dev/sda3  1%
/dev/sda1  13%

两个字段空格显示结果不会空格

[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1 $5 } '
/dev/sda23%
/dev/sda31%
/dev/sda113%

也可以设置分隔符。

==表示的是分隔符,也是字符串,一定要加双引号引起来。

$1是变量,不能加上双引号。

[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1"=="$5 } '
/dev/sda2==3%
/dev/sda3==1%
/dev/sda1==13%
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1 "==" $5 } '
/dev/sda2==3%
/dev/sda3==1%
/dev/sda1==13%
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1 	 $5 } '
awk: cmd. line:1:  { print  $1 	 $5 } 
awk: cmd. line:1:              ^ backslash not last character on line
awk: cmd. line:1:  { print  $1 	 $5 } 
awk: cmd. line:1:              ^ syntax error
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1 "
" $5 } '
/dev/sda2
3%
/dev/sda3
1%
/dev/sda1
13%
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1 
 $5 } '
awk: cmd. line:1:  { print  $1 
 $5 } 
awk: cmd. line:1:              ^ backslash not last character on line
awk: cmd. line:1:  { print  $1 
 $5 } 
awk: cmd. line:1:              ^ syntax error
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  $1
$5 } '
awk: cmd. line:1:  { print  $1
$5 } 
awk: cmd. line:1:             ^ backslash not last character on line
awk: cmd. line:1:  { print  $1
$5 } 
awk: cmd. line:1:             ^ syntax error

把整行都打印出来,加上$0。

print默认就是把整行的内容打印出来。

[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print  } '
/dev/sda2       51175000 1421928  49753072   3% /
/dev/sda3       20961280   32948  20928332   1% /app
/dev/sda1        1038336  126596    911740  13% /boot
[root@centos77 ~]# df  |  grep   /dev/sd |  awk  ' { print   $0  } '
/dev/sda2       51175000 1421928  49753072   3% /
/dev/sda3       20961280   32948  20928332   1% /app
/dev/sda1        1038336  126596    911740  13% /boot

(七)打印含有bash的行

[root@centos72 ~]# awk '/bash/' /etc/passwd  | head
root:x:0:0:root:/root:/bin/bash
wang:x:1000:1000:wang:/home/wang:/bin/bash
std01:x:1001:1002::/home/std01:/bin/bash
std02:x:1002:1003::/home/std02:/bin/bash
std03:x:1003:1004::/home/std03:/bin/bash
std04:x:1004:1005::/home/std04:/bin/bash
std05:x:1005:1006::/home/std05:/bin/bash
std06:x:1006:1007::/home/std06:/bin/bash
std07:x:1007:1008::/home/std07:/bin/bash
std08:x:1008:1009::/home/std08:/bin/bash
[root@centos72 ~]# awk 'bash' /etc/passwd  | head

(八)打印特定字段符合条件的行

打印第3个字段uid是1000的行

[root@centos72 ~]# awk   -F":"   '$3==1000' /etc/passwd 
wang:x:1000:1000:wang:/home/wang:/bin/bash

最好加双引号

[root@centos72 ~]# awk   -F":"   '$3=="1000"' /etc/passwd 
wang:x:1000:1000:wang:/home/wang:/bin/bash

打印第1个字段用户名是root的行

注意字符串要加双引号

[root@centos72 ~]# awk   -F":"   '$1=="root"' /etc/passwd 
root:x:0:0:root:/root:/bin/bash

(九)打印行序号符合条件的行

打印行序号小于10的行

[root@centos72 ~]# awk   -F":"    'NR<10'  /etc/passwd
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@centos72 ~]# head  /etc/passwd
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@centos72 ~]# head  /etc/passwd  | wc
     10      10     385
[root@centos72 ~]# awk   -F":"    'NR<10'  /etc/passwd  |  wc
      9       9     340

打印行序号小于等于10的行

[root@centos72 ~]# awk   -F":"    'NR<=10'  /etc/passwd  
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@centos72 ~]# awk   -F":"    'NR<=10'  /etc/passwd   |  wc
     10      10     385

(十)awk结合sed进行查找替换

查找用户名为daemond的行,并且替换为wu

[root@centos72 ~]# awk   -F":"    '$1=="daemon"'  /etc/passwd   
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@centos72 ~]# awk   -F":"    '$1=="daemon"'  /etc/passwd   |  sed  's/daemon/wu/'

注意上面的命令仅仅是测试,么有真正执行

[root@centos72 ~]# cat  /etc/passwd  |head
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin


作者:wang618
出处:https://www.cnblogs.com/wang618/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/wang618/p/11226574.html