awk命令用法举例

基本用法:
awk '{pattern + action}' filename
pattern: 查找的内容或者正则表达式
action: 找到匹配内容后,所执行的一系列命令

awk调用的3种方式:
1.命令行方式
awk [-F filed-separator] 'commands' input-file(s)
其中,commands是真正的awk命令,[-F域分隔符]是可选的,input-file(s)是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项都为一个域。
不指定-F域分隔符的话,默认的分隔符都是空格。

2.shell脚本方式
将所有的awk命令插入一个文件,并使用awk程序去执行。需要注意的是:必须将awk命令解释器
作为脚本的首行(#!bin/awk)。相当于shell脚本首行的:#!bin/sh

3.将所有的awk命令插入到一个单独文件,然后调用.
awk -f awk-script-file input-file(s)
其中,-f选项是加载awk-script-file文件,input-file(s)是待处理的文件。

举例说明:
1.显示最近登录的5个账号名称: last -n 5
1)显示最近登录的5个账号信息
[hduser0401@dev-l002782 ~]$ last -n 5
hduser04 pts/52       10.50.116.84     Thu Sep  8 10:48   still logged in   
ex-wugua pts/4        10.13.96.106     Thu Sep  8 10:37   still logged in   
ex-zhoub pts/51       10.13.96.117     Thu Sep  8 10:29   still logged in   
ex-zhoub pts/13       10.13.97.152     Thu Sep  8 10:23   still logged in   
ex-zhoub pts/13       10.13.97.152     Thu Sep  8 10:22 - 10:23  (00:00)    

2)只显示账号
[hduser0401@dev-l002782 ~]$ last -n 5 | awk '{print $1}'
hduser04
ex-wugua
ex-zhoub
ex-zhoub
ex-zhoub

awk工作的流程是这样的: 读入有'\n'换行符分隔的一条记录,然后将记录按指定的域分隔符划分。
$0表示所有域(即整条记录),$1表示第1个域,$n表示第n个域。默认域分隔符为"空白键"或者"tab键"。
因此上面的$1表示登录用户,$3表示IP,以此类推.

2.只显示/etc/passwd的账户
cat /etc/passwd | awk -F ':' '{print $1}'
awk -F ':' '{print $1}' /etc/passwd

3.只显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分隔
cat /etc/passwd | awk -F ':' '{print $1"\t"$7}'
awk -F ':' '{print $1"\t"$7}' /etc/passwd


4.只显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号键分隔,并且添加列名(name,shell),
末尾添加'blue,/bin/nosh'
awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}' /etc/passwd

awk工作的流程是这样的: 先执行BEGIN,然后读取文件,读入有'\n'换行符分隔的1条记录,然后将记录按指定的域分隔符划分。
$1表示第1个域,$n表示第n个域。接着开始读入第2条记录.。。直到所有的记录都读完,最后执行END操作。

扫描二维码关注公众号,回复: 2277488 查看本文章

5.搜索/etc/passwd中含有"root"的所有行:输出每一行的内容
[hduser0401@dev-l002782 ~]$ awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[hduser0401@dev-l002782 ~]$ awk -F: '/root/' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin

搜索一行记录(即不划分域),可以不用指定域分隔符

6.搜索/etc/passwd中含有"root"的所有行,并显示对应的shell
[hduser0401@dev-l002782 ~]$ awk -F: '/root/{print $7}' /etc/passwd
/bin/bash
/sbin/nologin
[hduser0401@dev-l002782 ~]$ awk -F ':' '/root/{print $7}' /etc/passwd
/bin/bash
/sbin/nologin

这里指定了action{print $7}, 另外: -F:和-F ':'效果相同

7.搜索root开头的所有行
[hduser0401@dev-l002782 ~]$ awk '/^root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash

AWK常用内置变量
ARGC      命令行参数个数
ARGV      命令行参数排列
ENVIRON   支持队列中系统环境变量的使用
FILENAME  awk浏览的文件名
FNR       浏览文件的记录数
FS        设置输入域分隔符,等价于命令行-F选项
NF        浏览记录的域个数
NR        已读取的记录数
OFS       输出域分隔符
ORS       输出记录分隔符
RS        控制记录分隔符

8.统计/etc/passwd:文件名,每行的行号,每行的列数(域个数),以及对应的完整行内容:
[hduser0401@dev-l002782 ~]$ awk -F ':' '{print "filename=" FILENAME ",linenumber=" NF ",columns=" NR ",linecontent=" $0}' test0908.txt
filename=test0908.txt,linenumber=2,columns=1,linecontent=1:huangbiquan
filename=test0908.txt,linenumber=2,columns=2,linecontent=2:martin
filename=test0908.txt,linenumber=3,columns=3,linecontent=3:ella:lee
filename=test0908.txt,linenumber=1,columns=4,linecontent=4,bital,peter
filename=test0908.txt,linenumber=3,columns=5,linecontent=5:jane:bital
filename=test0908.txt,linenumber=3,columns=6,linecontent=bital:jamie:jimmy
filename=test0908.txt,linenumber=5,columns=7,linecontent=6:annie:kevin:roy:hunter
      
可以使用printf代替print:
[hduser0401@dev-l002782 ~]$ awk -F ':' '{printf("filename=:%10s,linenumber=:%s,columns=:%s,linecontent=:%s\n"),FILENAME,NF,NR,$0}' test0908.txt
filename=:test0908.txt,linenumber=:2,columns=:1,linecontent=:1:huangbiquan
filename=:test0908.txt,linenumber=:2,columns=:2,linecontent=:2:martin
filename=:test0908.txt,linenumber=:3,columns=:3,linecontent=:3:ella:lee
filename=:test0908.txt,linenumber=:1,columns=:4,linecontent=:4,bital,peter
filename=:test0908.txt,linenumber=:3,columns=:5,linecontent=:5:jane:bital
filename=:test0908.txt,linenumber=:3,columns=:6,linecontent=:bital:jamie:jimmy
filename=:test0908.txt,linenumber=:5,columns=:7,linecontent=:6:annie:kevin:roy:hunter

AWK提供两个打印函数
print: 参数可以是变量、数值或者字符串。其中变量和数值可以直接放在print后面,但是字符串必须要用双引号,参数间使用逗号分隔(作用和空格相同)
printf: 与C语言中的printf基本相同,可以格式化字符串,输出复杂时,使用printf更方便.


AWK编程: 除了内置变量,还可以自定义变量

9.统计/ect/passwd中账户的数量
awk '{i++;print $0;} END {print "User count is "i}' /etc/passwd

[hduser0401@dev-l002782 ~]$ awk '{i++;print $0;} END {print "User count is "i}' test0908.txt
1:huangbiquan
2:martin
3:ella:lee
4,bital,peter
5:jane:bital
bital:jamie:jimmy
6:annie:kevin:roy:hunter
User count is 7

说明:action{}里面只有1个print,action{}可以有多个语句,以;隔开。print是其中一个语句。

[hduser0401@dev-l002782 ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size/1024/1024,"M"}'
end size is 2.53965 M

10.统计某个文件夹下文件占用的字节数
1)逗号分隔(作用和空格相同)
[hduser0401@dev-l002782 ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size}'
end size is 2663040
[hduser0401@dev-l002782 ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is "size}'
end size is 2663040
2)单位改成M
[hduser0401@dev-l002782 ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size/1024/1024,"M"}'
end size is 2.53965 M
注意:这里的统计部包括文件夹子目录

AWK条件语句: 从C语言借鉴过来的
主要有以下三种:
if, if+else, if+else if+else

11.统计某个文件夹下文件占用的字节数,过滤掉字节数等于4096的文件
[hduser0401@dev-l002782 ~]$ ls -l |awk 'BEGIN {size=0;print "start size is",size;} {if($5!=4096){size=size+$5;}} END {print "end size is",size/1024/1024,"M"}'
start size is 0
end size is 2.50501 M

说明:对于{}中的最后一个语句,后面的;可以去掉

AWK中的循环语句: 同样从C语言借鉴过来的
支持的循环语句有: while, do/while, for, break,continue

12.显示/etc/passwd文件中账户
awk -F ':' 'BEGIN {i=0;}{name[i]=$1;i++} END {for(i=0; i<NR; i++) print i, name[i]}' /etc/passwd

[hduser0401@dev-l002782 ~]$ awk -F ':' 'BEGIN {i=0;}{name[i]=$1;i++} END {for(i=0; i<NR; i++) print i, name[i]}' test0908.txt
0 1
1 2
2 3
3 4,bital,peter
4 5
5 bital
6 6

猜你喜欢

转载自blog.csdn.net/qq646748739/article/details/81131448