码迷,mamicode.com
首页 > 系统相关 > 详细

Linux awk命令使用

时间:2018-04-08 15:59:33      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:Linux awk命令使用

Linux awk命令使用



目录


笔记日期20180408



awk

1. print

2. 变量FS,OFS,NF,NR

3. printf命令

4. 操作符

5. PATTERN







Introduction


Gawk  is  the GNU Project's implementation of the AWK programming lan-

guage.  It conforms to the definition of the  language  in  the  POSIX

1003.1  Standard.  This version in turn is based on the description in

The AWK Programming Language, by Aho, Kernighan, and Weinberger.  Gawk

provides  the additional features found in the current version of UNIX

awk and a number of GNU-specific extensions.


The command line consists of options to gawk itself, the  AWK  program

text  (if not supplied via the -f or --file options), and values to be

made available in the ARGC and ARGV pre-defined AWK variables.


Pgawk is the profiling version of gawk.  It is identical in every  way

to  gawk,  except  that programs run more slowly, and it automatically

produces an execution profile in the file awkprof.out when done.   See

the --profile option, below.


Dgawk  is an awk debugger. Instead of running the program directly, it

loads the AWK source code and then  prompts  for  debugging  commands.

Unlike  gawk  and  pgawk, dgawk only processes AWK program source pro?

vided with the -f option.  The debugger is documented in GAWK:  Effec?

tive AWK Programming.



awk 报告生成工具,格式化文本输出


gawk - pattern scanning and processing language

基本用法: gawk [options] 'program' file ...

program: PATTERN{ACTION STATEMENTS}

语句之间分号分隔

选项:

-F 指明输入时用到的字段分隔符

-v var=value: 自定义变量

1. print

print item1, item2, ...

要点:

(1) 逗号分隔符

(2) 输出的各item可以字符串,也可以是数值,当前记录的字段、变量、或awk表达式

(3) 如省略item,相当于print $0 即全部输出

# awk -F: '{print "hello  " $1,$2}' /etc/passwd

每行会打印一个hello字符

2. 变量

2.1 内建变量

此处只给命令行,执行效果,有兴趣可以直接放到命令行里查看

FS: input field seperator, 默认为空白字符

OFS: output field seperator, 默认为空白字符

# awk -v FS=":" -v OFS=" ++ " '{print $1,$2}' /etc/passwd

# awk '{FS=":";OSF=" ++ ";print $1,$2}' /etc/passwd

两条命令含义一样,只是不同的格式

RS: input record seperator,输入时的换行符

ORS: output record seperator, 输出时的换行符

# awk '{RS="\n";ORS="--------";print $0}' /etc/passwd

这个表示更换换行符

NF: number of field, 每一行的字段数

# awk '{print NF}' /etc/fstab

打印出每一行的字段数

# awk '{print $NF}' /etc/fstab

打印出最后一个字段的字符串,是因为将变量替换成数值,而数字加$符号表示打印

具体某个字段,所以最后才会出现打印最后一个字段的字符串

NR: number of record, 显示文件的行数

# awk '{print NR}' /etc/fstab

FILENAME: 当前文件名

# awk '{print FILENAME}' /etc/fstab


ARGC: 命令行参数个数

# awk 'BEGIN{print ARGC}' /etc/fstab

这个会打印出2含义是awk这个命令后跟了两个参数

ARGV: 数组,保存的是命令行所给定的各参数

# awk '{print ARGV[1]}' /etc/fstab /etc/passwd

2.2 自定义变量

(1) -v var=value

变量区分字符大小写(在此前已经用过,只不过那是内建,此处只需要自定义即可)

# awk -v HE="hello" '{print HE,$1}' /etc/fstab

(2)在program中直接定义

# awk '{HE="hello";print HE,$1}' /etc/fstab

含义与上方的命令一样

3. printf命令

格式化输入: printf FORMAT, item1, item2, ...

(1) FORMAT必须要给出

(2) 不会自动换行,需要显式给出换行控制符,\n

(3) FORMAT中需要分别为后面的每个item指定一个格式化符号;

格式符(风格是C语言的,如果学过C应该很容易理解)

%c 显示字符的ASCII码;

%d,%i 显示十进制整数

%e,%E 科学计数法数值显示

%f 显示为浮点数

%g,%G 以科学计数法或浮点形式显示数值

%s 显示字符串

%u 无符号整数

%% 显示%自身

修饰符(也是C语言里的东东)

用来格式化输出,如每个字段给几个字符等

#[.#] 第一个数字控制显示的宽度,第二个#表示小数点后的精度

%3.1f

- 左对齐

+ 显示数值的符号

# awk -F: '{printf "UserName: %s\n",$1}' /etc/passwd

将所有的用户名打印出来,并在其前方加入Username:

# awk -F: '{printf "UserName: %-30s   UserID: %s\n",$1,$3}' /etc/passwd

这条效果更工整

4. 操作符

算术操作符

x+y, x-y, x*y, x/y, x^y, x%y

-x

+x 转换为数值

字符串操作符:没有符号的操作符,字符串连接

赋值操作符

=, +=, -=, *=, /=, %=, ^=

++, --

比较操作符

>, >=, <, <=, +=, ==

模式匹配符

~ 是否匹配

!~ 是否不匹配

逻辑操作符

&&

||

!

函数调用C风格

function_name(argu1,argu2,...)

条件表格式C风格

selector?if-true-expression:if-false-expression

此条命令可以区别user是系统用户还是普通用户,系统打印sysUser,普通打印Common

# awk -F: '{$3>1000?type="Common User":type="SysUser";printf "%15s %s\n",$1,type}' /etc/passwd


5. PATTERN

(1) empty 空模式,匹配每一行

(2) /regular expression/ 仅处理能够被此处的模式匹配到的行

(3) relational expression 关系表达式:结果有真假区分,

结果为真被处理,结果为非0值,非空字符串不处理

显示普通用户

# awk -F: '$3>1000{print $1}' /etc/passwd

显示shell为bash的用户

# awk -F: '$NF=="/bin/bash"{print $1,$7}' /etc/passwd

# awk -F: '$NF~"bash$"{print $1,$7}' /etc/passwd

下边这条属于前边的变量值是否匹配后边的模式,匹配则会显示

(4) line ranges 行范围

startline,endline /patter1/,/pattern2/

# awk -f: '/^root/,/^f/{print $1}' /etc/passwd

# awk -F: '(NR>10&&NR<20){print $1}' /etc/passwd

(5) BEGIN/END模式

BEGIN{} 仅在开始处理文件中的文本之前执行一次

END{} 仅在处理完成之后执行一次


# awk -F: 'BEGIN{print "UserName             UID     \n -----------------------"};{printf "%-20s %s\n",$1,$3}END{print "===================\n It is end"}' /etc/passwd

(6) 常用的action

1 expressions: print, printf

2 Control statements: if, while等

3 Compound statements: 组合语句

4 Input statements

5 Output statements

(7) 控制语句

if(condition) {statments}

if(condition) {statements} else {statements}

while(condition) {statements}

do {statements} while(condition)

for(expr1,expr2,expr3) {statements}

break

continue

delete array[index]

delete array

exit

{ statements }


7.1 if-else

语法: if(condition) statement [else statement]

应用场景:对awk取得的整行或某个字段做条件判断


使用if语句判断/etc/apsswd的用户是系统用户还是普通用户

# awk -F: '{if($3>1000) {print "Com-User: ",$1,$3} else {print "Sys-User",$1,$3}}' /etc/passwd


输出默认shell为bash的用户

# awk -F: '{if($7~/bash$/) {print $1} }' /etc/passwd


输出一行字段大于5的行

# awk '{if(NF>5) {print $0} }' /etc/fstab


输出硬盘使用率大于20%的硬盘卷

# df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>20) {print $1} }'



7.2 while循环

语法: while(condition) statement

条件"真",进入循环;条件"假",退出循环;


应用场景:对一行内的多个字段逐一类似处理时使用

  对数组中的各元素逐一处理时使用


统计每个字段的长度

# awk '/^[[:space:]]*linux16/{w=1;while(w<=NF) {print $w,length($w);w++}}' /boot/grub2/grub.cfg


7.3 do-while循环

语法: do statement while(condition)

意义至少执行一次循环体


7.4 for循环

语法: for(expr1;expr2;expr3) statement


实现刚刚while所实现的功能

# awk '/^[[:space:]]*linux16/{for(w=1;w<=NF;w++) {print $w,length($w)}}' /boot/grub2/grub.cfg


for特殊用法

能够遍历数组中的元素

语法: for(var in array)


7.5 switch语句

语法: switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP/: statement; ... default: statement}


7.6 break和continue

break [n]

continue


7.7 next

提前结束对本行的处理而直接进入下一行


输出/etc/passwd中ID为偶数的用户(主要为了测试next用法)

# awk -F: '{if($3%2!=0) {next} else {print $1,$3} }' /etc/passwd

# awk -F: '{if($3%2!=0) {next};print $1,$3 }' /etc/passwd



(8) array

关联数组 array[index-expression]


index-expression

1.可以使用任意字符串,字符串要使用引号

2.如果某数组元素事先不存在,在引用时,awk会自动创建此元素,

  并将其值初始化为"空串".


若要判断数组中是否存在某元素,要使用"index in array"格式进行


weekdays[mon]="Monday"


若要遍历数组中的每个元素,要使用for循环

for (var in array) {for-body}


# awk 'BEGIN{for(i=1;i<=5;i++){weekday[i]=i};for(l in weekday){print weekday[l]}}'


注意:var会遍历array的每个索引

state["LISTEN"]++

state["ESTABLISHED"]++


输出现在主机上各状态连接个数

# netstat -tna | awk '/^tcp\>/{stat[$6]++}END{for(i in stat){print i,stat[i]}}'


输出http的log中每个IP访问次数

# awk '{ipnum[$1]++}END{for(i in ipnum){print i,ipnum[i]}}' /var/log/httpd/access_log


(9) 函数

9.1 内置函数

数值处理

rand() 返回0-1之间的随机数


字符串处理

length([s]) 返回指定字符串的长度

sub(r,s,[t]) 以r表示的模式来查找t所表示的字符串中的匹配的内容,并将其第一

 次出现替换为s所表示的内容

gsub(r,s,[t]) 以r表示的模式来查找t所表示的字符串中的匹配的内容,并将其

  所有匹配到的替换为s所表示的内容

split(s,a[,r]) 以r为分隔符切换字符s,并将切割后的结果保存至a所表示的数组中


将远端ip输出并不带后边的端口

# netstat -tna | awk '/^tcp\>/{split($5,ip,":");print ip[1]}'


将远端IP输出并统计个数

# netstat -tna | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'



Linux awk命令使用

标签:Linux awk命令使用

原文地址:http://blog.51cto.com/winthcloud/2095653

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!