首页 > 代码库 > awk:基础篇+案例
awk:基础篇+案例
awk提供了很强大的功能,它是linux中功能最强大的数据处理引擎之一,它不仅可以对文本数据进行搜索分析处理排序,还可以支持数学运算,含有内置函数和内置变量,甚至还可以进行一些脚本处理,编程。可以这么说,它可以根据发挥者的能力来起作用。
awk在linux中其实并不叫awk,而叫gawk
[root@libin ~]# which awk
/bin/awk
[root@libin ~]# ls -l /bin/awk
lrwxrwxrwx. 1 root root 4 Jun 29 17:14 /bin/awk –> gawk 它是链接指向gawk
awk的基本语法(基本格式):
awk [option]…….‘/PATTERN/{action}’ FILE…..
或者是awk [option]…..‘script’ FILE……因为awk本身就是一个类似于解释器的东西可以解释。
而有时候 ‘/PATTERN/{action}‘就相当于‘scrpit’ 相当于awk的脚本。
awk中的变量大致分两种,一种是内置的变量,一种可以允许你自定义变量。
awk的PATTERN有下列几种涵义:
PATTERN可以做地址定界
起始行,结束行
/pattern1/,/pattern2/
还可以特定某行
/pattern/
或直接加数字表示第几行
另外PATTERN还支持表达式的功能
比如:表达式中支持:
>,<,<=,>=,!=,==,~(模式匹配的)
另外PATTERN中还有两个比较特殊的一个是BEGIN,另一个是END。
BEGIN表示在后面action之前要做的动作,这些动作可以有初始化一些变量,在输出最开始显示一些东西。
而END表示后面action之后要做的动作。下面有示例
比如:取出系统上id号大于等于300的用户有哪些?
[root@libin ~]# awk -F: ‘$3 >= 300{print $1,$3}‘ /etc/passwd
rtkit 499
saslauth 498
nfsnobody 65534
pulse 497
mageedu 500
bob 501
zabbix 496
jimmy 502
…
这里笔者曾经犯过一次错误,笔者在写awk的时候,并没有加上-F: 分隔符,只是写成awk ‘$3 >= 300{print $1,$3}‘ /etc/passwd 结果屏幕并没有输出正确的信息,只是显示:
[root@libin ~]# awk ‘$3 >= 300 {print $1}‘ /etc/passwd
dbus:x:81:81:System
vcsa:x:69:69:virtual
avahi-autoipd:x:170:170:Avahi
rpcuser:x:29:29:RPC
nfsnobody:x:65534:65534:Anonymous
pulse:x:497:496:PulseAudio
zabbix:x:496:493:Zabbix
大家在这里引以为戒吧!
例子2、显示用户shell为bash的用户(可以让用户做模式匹配)
[root@libin ~]# awk -F: ‘$7 ~ /bash$/{print $1,$7}‘ /etc/passwd (这里模式匹配引用的内容一定要加//,如/要被引用的内容/
ageedu /bin/bash
bob /bin/bash
jimmy /bin/bash
bigbing /bin/bash
mysql /bin/bash
例子3、在例子2的显示内容之前加上一句话how are you
[root@libin ~]# awk -F: ‘BEGIN{print "how are you"}$7 ~ /bash/ {print $1,$7}‘ /etc/passwd
how are you
root /bin/bash
mageedu /bin/bash
bob /bin/bash
jimmy /bin/bash
bigbing /bin/bash
注意这里如果想加入字串,一定要用双引号引出来,不然就会变成这样,比如笔者曾经忘记加双引号,结果就显示空白了。如:
加上END试试:
awk -F: ‘BEGIN {print "hello"}$7 ~ /bash$/{print $1,$7}END{print "thats all"}‘ /etc/passwd
hello
root /bin/bash
mageedu /bin/bash
bob /bin/bash
jimmy /bin/bash
bigbing /bin/bash
thats all
这里曾经笔者也犯过一个错误:在被引用的字串里使用了that’s all,就因为这个不起眼的 ’的符号,导致结果并没有输出出来。
所以一般没有必要给自己找麻烦就不用特殊符号。
在awk有很多内置变量:
NF:Number of Field 字段数,直接引用则表示每一行中字段的总数,是个具体的数字。
FS:Field Seperator,输入分隔符
OFS Output Field Seperator 输出的分隔符
在示例中多次引用passwd这个文件,但是多次例子中输出到屏幕上的分隔都是空格,如:
root /bin/bash
mageedu /bin/bash
如果我想让它以原始的文本输出到屏幕上的”:”号呢?
[root@libin ~]# awk ‘BEGIN{FS=":";OFS=":"}$1~/root$/{print $1,$7}END{print "admin"}‘ /etc/passwd
root:/bin/bash
admin这里就用FS取代了-F选项,并指定输出的分隔符为:
在awk中,引用变量的值,不需要以$开头,如果以$开头的变量,则是引用变量中的字段的值。
awk大致的工作模式是这样的:
如果不是特别说明,awk会默认以空白字符作为分隔符,逐行的去做字符段的匹配。
而awk有自己内置的变量:举例来说:
如左图,假设line1有4个字段,默认以空白分隔符分隔,对于第一个字段,awk把它理解为$1,第二个字段,理解为$2,以此类推。这里比较特殊一点就是$0,它表示全部字段的内容。我们打个比方:
我们写一个示例:
[root@libin ~]# cat awk1.txt
tom and jerry are playing in the garden
[root@libin ~]#
这是一个只有一行的文本,下面用awk来进行取变量:
step1、先取出$1:
[root@libin ~]# awk -F‘ ‘ ‘{print $1}‘ ./awk1.txt
tom 如果没有特殊要求,它默认是以空白为分隔符的,所以-F ‘ ‘ 可以进行省略。
[root@libin ~]# awk ‘{print $1}‘ ./awk1.txt
tom
step2、取出第一和第三个字段
[root@libin ~]# awk ‘{print $1,$3}‘ ./awk1.txt
tom jerry 这里使用,号隔开的,其结果输出到标准输出(屏幕)上时,出现了tom jerry,这里如果我们不使用,会是什么样子的效果?
step3、如果在{}中$1和$3之间不加符号隔开
[root@libin ~]# awk ‘{print $1$3}‘ ./awk1.txt
tomjerry 这里tomjerry被粘合在了一起
设想,如果我们人为的加些符号在里面,可以出现什么效果呢?
[root@libin ~]# awk ‘{print $1-$3}‘ ./awk1.txt 这里加上 - 符号
0
[root@libin ~]# awk ‘{print $1is$3}‘ ./awk1.txt 这里加上了 is
tomjerry
[root@libin ~]# awk ‘{print $1&&$3}‘ ./awk1.txt 这里加上&&符号
1
[root@libin ~]# awk ‘{print $1 $3}‘ ./awk1.txt 这里加上了空白字符
tomjerry输出都不尽相同,可见符号在awk的{}有着不同的意思。以后在使用awk的时候务必要小心,否则一个不注意有可能就得不到想要的结果。
step4、如果我想整行都显示出来
[root@libin ~]# awk ‘{print $0}‘ awk1.txt
tom and jerry are playing in the garden 这里的效果类似grep ‘[[:alnum:]]\+’ awk1.txt
step5、有一个变量叫做NF,我如果在awk的program中写入NF表示什么呢?
[root@libin ~]# awk ‘{print NF}‘ awk1.txt
8
出现了数字8,再仔细看看文本中 tom and jerry are playing in the garden 以空格分开一共8段,原来NF表示每一行里字段的总个数。
step5、那么$NF是什么呢?
[root@libin ~]# awk ‘{print $NF}‘ awk1.txt
garden 对照tom and jerry are playing in the garden字段,原来$NF表示每一行里最后一个字段的内容。
step6、显示gid小于500的组
[root@libin ~]# awk -F: ‘BEGIN{print "this is context"}$3 < 500{print $1,$3}‘ /etc/passwd
this is context
root 0
bin 1
daemon 2
…
或者
[root@libin ~]# awk ‘BEGIN{FS=":";print "this is context"}$3 < 500{print $1,$3}‘ /etc/passwd
this is context
root 0
bin 1
daemon 2
step7、显示默认shell为nologin的用户:
awk ‘BEGIN{FS=":"}$7~/nologin$/{print$1,$7}‘ /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
step8、显示eth0网卡配置文件的配置信息,只显示=后面的内容
[root@libin ~]# awk ‘BEGIN{FS="="}{print $2}‘ /etc/sysconfig/network-scripts/ifcfg-eth0
eth0
dhcp
00:0c:29:7b:06:ec
yes
yes
Ethernet
172.16.249.126
step9、显示/etc/sysctl.conf文件中定义的内核参数的参数名称
[root@libin ~]# awk ‘$1~ /kernel.*/{print $1}‘ /etc/sysctl.conf
kernel.sysrq
kernel.core_uses_pid
kernel.msgmnb
kernel.msgmax
kernel.shmmax
kernel.shmall
step10、显示eth0网卡的ip地址
[root@libin ~]# ifconfig eth0 | awk -F: ‘$1 ~ /inet addr.*/ {print $1,$2}‘ | awk ‘{print $1,$2,$3}‘
inet addr 192.168.1.146
如上是awk的最基础的用法,下篇还有awk的高级用法。
awk:基础篇+案例