Linux--awk命令
2019-08-26 本文已影响0人
李小李的路
概述
- awk为程序员提供了完整的编程模型,awk程序由一个主输入循环(main input loop)维持,主输入循环反复执行,直到终止条件被触发。awk已经搭好了主输入循环框架,程序员写的代码被嵌入到主输入循环框架中执行。例如在java中,程序员需要写一个main函数,打开文件、读取文件行、进行相应处理,关闭文件,awk自动完成了上述步骤。
- awk还定义了两个特殊的字段,BEGIN和END,BEGIN用于在主输入循环之前执行,即在未读取文件行之前执行,END在主输入循环之后执行,即在读取输入行完毕后执行。
- 简单的说,awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk使用方法
- awk语句都是由模式和动作组成,模式是一组用于测试输入行是否需要执行动作的规则,动作是包含语句、函数和表达式的执行过程。简而言之,模式决定动作何时触发和触发事件,动作执行对输入行的处理。
- awk [-F 域分隔符] ‘awk程序段’输入文件
- awk -f awk脚本文件 输入文件
- 基本命令格式如下:
case-1:
[root@localhost ~]# awk '条件1 {动作 1} 条件 2 {动作 2} …' 文件名
case-2:
awk '{pattern + action}' {filenames}
awk条件(pattern)
awk支持的主要条件.png例如:
x>10:判断变量 x 是否大于10;
x == y:判断变量 x 是否等于变量 y;
A~B:判断字符串 A 中是否包含能匹配 B 表达式的子字符串;
A!~B:判断字符串 A 中是否不包含能匹配 B 表达式的子字符串;
- awk内置函数
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
awk动作(action)
格式化输出;
流程控制语句;
awk调用的三种方式
1.命令行方式
awk [-F field-separator] 'commands' input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk
3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
awk入门案例
- 按逗号分隔符获取最后5行,第3列;(awk的默认分隔符为空格)
[liyahui@172 14]$ tail -n 5 /etc/passwd | awk '{print $1}'
root
root
root
dmtsai
root
awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,以此类推。
- 如果只是显示/etc/passwd的账户
#cat /etc/passwd |awk -F ':' '{print $1}'
root
daemon
bin
sys
- 这种是awk+action的示例,每行都会执行action{print $1}。
- -F指定域分隔符为':'。
- 如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割;
#cat /etc/passwd |awk -F ':' '{print $1"\t"$7}'
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
- 如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh
- awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
- 搜索/etc/passwd有root关键字的所有行
#awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
- 这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。
- 搜索支持正则,例如找root开头的: awk -F: '/^root/' /etc/passwd
- 搜索/etc/passwd有root关键字的所有行,并显示对应的shell
# awk -F: '/root/{print $7}' /etc/passwd
/bin/bash
- 这里指定了action{print $7}
- 统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
#awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
- 使用printf替代print,可以让代码更加简洁,易读
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
print和printf
- awk中同时提供了print和printf两种打印输出的函数。
- 其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
- printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
awk编程
- 变量和赋值
- 除了awk的内置变量,awk还可以自定义变量。
- 下面统计/etc/passwd的账户人数
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is 40
- count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。
这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0,如下:
awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
[start]user count is 0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is 40
- 统计某个文件夹下的文件占用的字节数
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
[end]size is 8657198
- 如果以M为单位显示:
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
[end]size is 8.25889 M
- 注意,统计不包括文件夹的子目录。
awk面试题
参考博客:
linux 之shell篇 awk命令
Shell awk命令详解(格式+使用方法)
https://www.cnblogs.com/chenhuan001/p/6297615.html
shell 强大的awk
Shell编程之AWK的使用