awk:基础篇+案例

awk提供了很强大的功能,它是linux中功能最强大的数据处理引擎之一,它不只能够对文本数据进行搜索分析处理排序,还能够支持数学运算,含有内置函数和内置变量,甚至还能够进行一些脚本处理,编程。能够这么说,它能够根据发挥者的能力来起做用。mysql

awk在linux中其实并不叫awk,而叫gawklinux

[root@libin ~]# which awk
/bin/awk
[root@libin ~]# ls -l /bin/awk
lrwxrwxrwx. 1 root root 4 Jun 29 17:14 /bin/awk –> gawk 它是连接指向gawksql

awk的基本语法(基本格式):shell

awk  [option]…….'/PATTERN/{action}’ FILE…..编程

或者是awk [option]…..'script’ FILE……由于awk自己就是一个相似于解释器的东西能够解释。bash

而有时候 '/PATTERN/{action}'就至关于'scrpit’ 至关于awk的脚本。ide

awk中的变量大体分两种,一种是内置的变量,一种能够容许你自定义变量。函数

awk的PATTERN有下列几种涵义:this

PATTERN能够作地址定界blog

起始行,结束行

/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

你们在这里引觉得戒吧!

例子二、显示用户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

例子三、在例子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

注意这里若是想加入字串,必定要用双引号引出来,否则就会变成这样,好比笔者曾经忘记加双引号,结果就显示空白了。如

image

加上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,就由于这个不起眼的 ’的符号,致使结果并无输出出来。

image 因此通常没有必要给本身找麻烦就不用特殊符号。


在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大体的工做模式是这样的:

image 若是不是特别说明,awk会默认以空白字符做为分隔符,逐行的去作字符段的匹配。

而awk有本身内置的变量:举例来讲:

image  如左图,假设line1有4个字段,默认以空白分隔符分隔,对于第一个字段,awk把它理解为$1,第二个字段,理解为$2,以此类推。这里比较特殊一点就是$0,它表示所有字段的内容。咱们打个比方:

咱们写一个示例:

[root@libin ~]# cat awk1.txt
tom and jerry are playing in the garden
[root@libin ~]#

这是一个只有一行的文本,下面用awk来进行取变量:

step一、先取出$1:

[root@libin ~]# awk -F' ' '{print $1}' ./awk1.txt 
tom                                                               若是没有特殊要求,它默认是以空白为分隔符的,因此-F ‘ ‘ 能够进行省略。

[root@libin ~]# awk  '{print $1}' ./awk1.txt
tom

step二、取出第一和第三个字段

[root@libin ~]# awk '{print $1,$3}' ./awk1.txt
tom jerry                                                        这里使用,号隔开的,其结果输出到标准输出(屏幕)上时,出现了tom jerry,这里若是咱们不使用,会是什么样子的效果?

step三、若是在{}中$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的时候务必要当心,不然一个不注意有可能就得不到想要的结果。

step四、若是我想整行都显示出来

[root@libin ~]# awk '{print $0}' awk1.txt
tom and jerry are playing in the garden           这里的效果相似grep ‘[[:alnum:]]\+’ awk1.txt

step五、有一个变量叫作NF,我若是在awk的program中写入NF表示什么呢?

[root@libin ~]# awk '{print NF}' awk1.txt
8

出现了数字8,再仔细看看文本中 tom and jerry are playing in the garden 以空格分开一共8段,原来NF表示每一行里字段的总个数。

step五、那么$NF是什么呢?

[root@libin ~]# awk '{print $NF}' awk1.txt
garden                                                    对照tom and jerry are playing in the garden字段,原来$NF表示每一行里最后一个字段的内容。

step六、显示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

step七、显示默认shell为nologin的用户:

awk 'BEGIN{FS=":"}$7~/nologin$/{print$1,$7}' /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin

step八、显示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

step九、显示/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

step十、显示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的高级用法。

相关文章
相关标签/搜索