Linux三剑客之awk命令详解

版权声明:转载请注明出处! https://blog.csdn.net/wfs1994/article/details/81906850

awk简单入门

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

使用方法:

awk '{pattern + action}' {filenames}

常见用法示例:
1.$1:第一列,$0:整行,$NF:显示最后一个字段

# awk -F':' '{print $1}' /etc/passwd   # 打印第一列
root
bin
...

# awk -F ':' '{print $NF}' /etc/passwd     # 打印最后一列
/bin/bash
/sbin/nologin
...

2.NR指定行号

# awk '{if (NR>=2 && NR<5 ) print $0}' /etc/passwd     # 显示2到4行
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

3.-F指定分隔符,可指定一个或多个(默认空格);+:把多个连续的分隔符变为一个

# ifconfig eth0|awk -F '[ :]+' 'NR==2 {print $4}'      #获取eth0 ip地址
192.168.0.135

printf命令

格式:printf format, item1, item2, ...

要点:

  • 1、其与print命令的最大不同是,printf需要指定format;
  • 2、format用于指定后面的每个item的输出格式;
  • 3、printf语句不会自动打印换行符;\n

format格式的指示符都以%开头,后跟一个字符;如下:

%c: 显示字符的ASCII码;
%d, %i:十进制整数;
%e, %E:科学计数法显示数值;
%f: 显示浮点数;
%g, %G: 以科学计数法的格式或浮点数的格式显示数值;
%s: 显示字符串;
%u: 无符号整数;
%%: 显示%自身;

修饰符:

N: 显示宽度;
-: 左对齐;
+:显示数值符号;

示例:

# awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd
root            0
bin             1
daemon          2
adm             3

模式&动作

awk中每一个语句(statements)都由两部分组成:模式(pattern)和相应的动作(actions)。只要模式匹配,awk就会执行相应的动作。动作部分由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。

常见的模式类型:
1、Regexp: 正则表达式,格式为/regular expression/

# awk -F: '/^r/ {print $1}' /etc/passwd
root

2、expresssion:表达式,其值非0或为非空字符时满足条件,
如:$1 ~ /foo/$1 == "str",用运算符~(匹配)和!~(不匹配)

awk -F: '$3>=500 {print $1,$3}' /etc/passwd
awk -F: '$7~/bash$/ {print $1,$7}' /etc/passwd
awk -F: '$7!~/bash$/ {print $1,$7}' /etc/passwd

3、Ranges:指定的匹配范围,格式为pat1,pat2

# awk -F: '/^r/,$7~/nologin/ {print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin

4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次

# awk -F: 'BEGIN{print "username      id     bash"} {printf "%-15s%-5s%-20s\n",$1,$3,$7}' /etc/passwd    
username      id     bash
root           0    /bin/bash           
bin            1    /sbin/nologin       
daemon         2    /sbin/nologin 
......

# awk '{count++;print $0;} END{print "user count is ",count}' /etc/passwd      # 统计/etc/passwd的账户人数                                                                 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
......
user count is  34

# ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "size is ",size}'     # 统计某个文件夹下的文件占用的字节数:
# ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "size is ",size/1024/1024,"M"}'

5、Empty(空模式):匹配任意输入行;

常见的Action:

  • 变量或数组赋值
  • 输入/输出语句
  • 内置函数和自定义函数
  • 流程控制语句

控制语句

1.if-else
语法:if (condition) {then-body} else {[ else-body ]}

awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd
awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd
awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

2.while
语法:while (condition){statement1; statment2; ...}

awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd
awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd

3.do-while
语法:do {statement1, statement2, ...} while (condition)

awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd

4.for
语法:for ( variable assignment; condition; iteration process) { statement1, statement2, ...}

awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd

for循环还可以用来遍历数组元素:
语法: for (i in array) {statement1, statement2, ...}

awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd

awk数组

array[index-expression]

index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。

要遍历数组中的每一个元素,需要使用如下的特殊结构:for (var in array) { statement1, ... }其中,var用于引用数组下标,而不是元素值;

netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引;

数组的典型应用:
1.查看TCP连接状态

netstat -na |awk '/^tcp/ {print $6}'|sort|uniq -c|sort -rn
netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print a,s[a]}'

2.分析图片服务日志,把日志(每个图片访问次数*图片大小的总和)排行,取top10,也就是计算每个url的总访问大小

awk '{array_num[$7]++;array_size[$7]+=$10} END{for(x in array_num){print array_size[x],array_num[x],x}}' access.log |sort -rn

猜你喜欢

转载自blog.csdn.net/wfs1994/article/details/81906850