工作原理:逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理
基本用法
awk 'pattern {action}' filenames
pattern:正则表达式
action:执行的命令
命令行:awk [-F flag] 'commands' filenames
file.txt 文件内容如下
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
例如 awk -F ':' '{print $1}' file.txt
root
daemon
bin
sys
sync
以:分割file.txt文件内容,输出第一个字段内容。-F 指定参数作为分隔符,多个分割符用 |,例如-F ",|#";-F ",|#+",+表示一个或多个#,$0是整行输出,$1是第一个字段,以此类推
$+n:表示第n个字段
$+NF:表示当前行有多少个字段,所以$NF表示最后一个字段,$(NF-1)表示倒数第二个字段
NR:表示当前处理的是第几行,例如 '{print NR}',打印行数
awk 函数
tolower()
:字符转为小写。length()
:返回字符串长度。substr()
:返回子字符串。sin()
:正弦。cos()
:余弦。sqrt()
:平方根。rand()
:随机数。1.算术函数:
int(x) 返回x的整数部分的值,值不会四舍五入,只是取整
sqrt(x) 返回x的平方根
rand() 返回伪随机数r,其中0<=r<1,(伪随机数指返回的值都是上一次返回的同一个随机数)
srand(x) 建立rand()新的种子数,如果没有指定就用当天的时间(使用srand()可以使得rand()返回不同的随机数)
例子:rand()产生一个随机数,通过srand()产生新的种子数,然后再差生一个随机数
awk 'BEGIN{print rand();srand();print rand()}'
2.字符串函数:
sub("要替换的字符串","替换后的字符串值"):替换匹配到的第一个文本
echo "hello world world" | awk '{sub("world","meitian");print $0}'
gsub("要替换的字符串","替换后的字符串值" ):开启全局替换,替换文本中所有匹配到的字符串
echo "hello world world" | awk '{gsub("world","meitian");print $0}'
自定义函数:
function 函数名(参数1,参数2,...){语句;return 表达式}
例子:求和
awk 'function sum(a,b){total=a+b;return total}BEGIN{print sum(2,3)}'
注意:函数必须写在BEGIN{}{}END{}的花括号之外的地方,不能放在任何{}内,否则会报错`return' used outside function context
awk数组类似于Python的字典,使用的是键值
a[1] = "hello"
a["name"] = "hello"
1和name是key,key可以是数字也可以是字符串,hello是value
数组元素的删除:delete a["name"]
192.168.3.2
192.168.3.2
192.168.3.3
192.168.3.4
a[$1]++解释:例子:awk '{a[$1]++}END{for(key in a)print (a[key],key)}'
awk是逐行读取的,读取第一行时,a[$1]替换为a[192.168.3.2]++,此时a[192.168.3.2]值是未定义的,但是后面跟了运算符++,awk会自动把0赋值给a[192.168.3.2],然后做++运算,此时得到的值为1,接着读取第二行a[192.168.3.2],此时a[192.168.3.2]经过上次运算值为1,这里再做一次++运算,即1+1,a[192.168.3.2]值变为2,继续读取下一行直到文件末尾,则数组a里面的key是$1,value是$1在文件出现的次数,也就是key出现的次数
awk不能直接修改源文件,可以通过重导向输出结果来修改原文件。>(全部覆盖文件内容)或>>(追加到文件)
awk '/^root/{print $0 >"passwd"}' passwd
注意:重导向输出的文件名要用双引号括起来,否则会报错