模式与操作
①基本模式为:
awk 'program' [ file...]
awk读取命令行所指定的各个文件(若无,则从标准输入),一次读取一条记录(行)
再针对每一行,引用程序所指定的命令。
②awk程序的基本架构为
pattern {act
pattern {act
...
pattern和act
省略act
③大部分单命令行程序格式如下:
... | awk '{ print some-stuff }' | ...
对每条记录而言,awk会测试程序里的每个pattern,若模式为真,则awk便执行act
使用方法
awk '{pattern + act
其中 pattern 表示 AWK 在数据中查找的内容,而 act
花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。
pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。
完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
调用awk
①.命令行方式
awk [-F field-separator] 'commands' input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
②.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk
③.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
实例1:打印字段
[gz_fieldyang@test ~]$ last -n 3
sninf_ke pts/2 172.20.204.18 Mon Mar 7 16:49 still logged in
gz_field pts/1 172.23.33.204 Mon Mar 7 16:47 still logged in
sninf_to pts/3 172.20.204.19 Mon Mar 7 16:39 - 16:44 (00:05)
wtmp begins Wed Jan 27 10:14:25 2016
[gz_fieldyang@test ~]$ last -n 3|awk '{print $1}'
sninf_ke #打印第一个字段,(未指定pattern)
gz_field
sninf_to
wtmp
[gz_fieldyang@ test ~]$ last -n 3|awk '{print $2,$5}'
pts/2 Mar #打印第2与第5个字段,(未指定pattern)
pts/1 Mar
pts/3 Mar
begins 27
[gz_fieldyang@ test ~]$ last -n 3|awk '{print $1,$NF}'
sninf_ke in #打印第一个与最后一个字段,(未指定pattern)
gz_field in
sninf_to (00:05)
wtmp 2016
[gz_fieldyang@ test ~]$ last -n 3|awk 'NF>0 {print $0}'
#打印非空行(指定pattern与act
sninf_ke pts/2 172.20.204.18 Mon Mar 7 16:49 still logged in
gz_field pts/1 172.23.33.204 Mon Mar 7 16:47 still logged in
sninf_to pts/3 172.20.204.19 Mon Mar 7 16:39 - 16:44 (00:05)
wtmp begins Wed Jan 27 10:14:25 2016
# $0为比较特别的字段,表示打印整条记录。
[gz_fieldyang@ test ~]$ last -n 3|awk 'NF>0'
#打印非空行(未指定act
sninf_ke pts/2 172.20.204.18 Mon Mar 7 16:49 still logged in
gz_field pts/1 172.23.33.204 Mon Mar 7 16:47 still logged in
sninf_to pts/3 172.20.204.19 Mon Mar 7 16:39 - 16:44 (00:05)
wtmp begins Wed Jan 27 10:14:25 2016
[gz_fieldyang@test ~]$
实例2:设置字段分隔字符 (awk -F...)
[gz_fieldyang@ test ~]$ last -n 2|awk -F/ 'NF>0 {print $1}'
sninf_ke pts
gz_field pts
wtmp begins Wed Jan 27 10:14:25 2016
[gz_fieldyang@ test ~]$ last -n 2|awk -F/ 'NF>0 {print $2}'
2 172.20.204.18 Mon Mar 7 16:49 still logged in
1 172.23.33.204 Mon Mar 7 16:47 still logged in
[gz_fieldyang@test ~]$
[gz_fieldyang@test ~]$ awk -F: '{print $1,$5}' /etc/passwd #处理/etc/paswwd
root root #管理账号
...
gz_kinma #实际用户
gz_fieldyang
...
实例3:改变字段分隔字符 (awk -v 'OFS=...')
[gz_fieldyang@test ~]$ awk -F: -v 'OFS=**' '{print $1,$5,$7}' /etc/passwd
root**root**/bin/bash
...
sninf_tonyhung****/bin/bash
gz_kinma****/bin/bash
gz_fieldyang****/bin/bash
....
实例4:打印行
[gz_fieldyang@test ~]$ awk -F: '{print "User",$1,"Shell is",$7}' /etc/passwd
User root Shell is /bin/bash #awk的print语句自动提供最后的换行字符,
User bin Shell is /sbin/nologin #各参数间使用逗号隔开
...
User gz_kinma Shell is /bin/bash
User gz_fieldyang Shell is /bin/bash
...
使用printf实现相同功能
[gz_fieldyang@test ~]$ awk -F: '{printf "User %s Shell is %s\n", $1,$7}' /etc/passwd
User root Shell is /bin/bash
User bin Shell is /sbin/nologin
...
User gz_kinma Shell is /bin/bash
User gz_fieldyang Shell is /bin/bash
...
注意:使用printf语句,最后需要使用\n转义序列使自己提供换行
起始与清除
BEGIN与END这两个特殊的”模式“,提供awk程序的起始(startup)和清除(cleanup)操作
常见于大型awk程序中,且通常写在个别文件中,而不是在命令行上
BEGIN {起始操作程序代码(startup co
pattern1 {act
pattern2 {act
END {清除操作程序代码(cleanup co
BEGIN和END代码块是可选的,习惯上(非必须)用于awk程序开头结尾,可以同时存在数个BEGIN与END语句块,
awk会按顺序执行:所有的BEGIN语句块都应放在起始处,而所有的END语句块放在结尾处
简单实例:
[gz_fieldyang@ test ~]$ awk 'BEGIN {FS=":" ;OFS="**"} #使用BEGIN设置变量
> {print $1,$3,$5}' /etc/passwd #被应用的程序继续第二行
root**0**root
bin**1**bin
....
gz_kinma**857** #输出,如前。
gz_fieldyang**859**