天天看点

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个账号信息

[[email protected] ~]$ 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)只显示账号

[[email protected] ~]$ 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操作。

5.搜索/etc/passwd中含有"root"的所有行:输出每一行的内容

[[email protected] ~]$ awk '/root/' /etc/passwd

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

[[email protected] ~]$ awk -F: '/root/' /etc/passwd

operator:x:11:0:operator:/root:/sbin/nologin

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

6.搜索/etc/passwd中含有"root"的所有行,并显示对应的shell

[[email protected] ~]$ awk -F: '/root/{print $7}' /etc/passwd

/bin/bash

/sbin/nologin

[[email protected] ~]$ awk -F ':' '/root/{print $7}' /etc/passwd

/bin/bash

/sbin/nologin

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

7.搜索root开头的所有行

[[email protected] ~]$ 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:文件名,每行的行号,每行的列数(域个数),以及对应的完整行内容:

[[email protected] ~]$ 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:

[[email protected] ~]$ 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

[[email protected] ~]$ 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是其中一个语句。

[[email protected] ~]$ 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)逗号分隔(作用和空格相同)

[[email protected] ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size}'

end size is 2663040

[[email protected] ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is "size}'

end size is 2663040

2)单位改成M

[[email protected] ~]$ 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的文件

[[email protected]v-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

[[email protected] ~]$ 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

继续阅读