【2】Linux文本处理工具三剑客--awk介绍及使用

一、awk介绍

awk是一种优良的文本处理工具

awk提供了极其强大的功能,可以进行样式装入,流控制,数学运算符,进程控制语句,甚至于内置的变量和函数,主要用于数据扫描、过滤、统计汇总工作

awk工具可以扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式

我们常使用sed和awk相结合的方式处理,使文本处理命令更快捷

 二、awk语法

awk 选项 命令 文件

awk  [-F | -f | -v ] ‘BEGIN {} / /{command1;command2} END {}’file

‘{}’      引用代码块

{…}   命令代码块,包含一条或多条命令

BEGIN    初始化代码块

/ str /        匹配代码块,可以是字符串或正则表达式

{print A;printB}         多条命令使用分号分隔

END       结尾代码块

awk选项:

 -F:定义字段分隔符,默认的分隔符是连续的空格,可以通过此选项任意指定

    awk '{print $1}' a.txt 

    awk -F: '{print $1,$2}' a.txt (以:为分隔符)

-v:参数传递,定义和引用变量,可以把外部变量引入到内部

  • 用-v指定  var=value 变量名区分大小写的
  • 在程序中直接定义
  • 在awk里,使用变量不用加$符号
  •     num1=10
  •     var="hello word"
        awk -v num1=$num2 -v var1="$var" `BEGIN{print num1,var1}`

-f:指定脚本

    vim test.awk

    #! /bin/bash

    BEGIN{print num2,var1}

   

    awk -v num2=$num1 -v var1=$var -f test.awk

-V:查看awk的版本号

awk命令:

读前处理BEGIN{awk_cmd1;awk_cmd2}:

    awk 'BEGIN {print "hello,World"}'

行处理:定址命令(正则表达式需要用/ /包围起来)

    awk -F: '/root/{print}' /etc/passwd

    awk -F: '$1~/root/{print}' /etc/passwd

    awk -F: '$1!~/root/{print}' /etc/passwd

读后处理END {awk_cmd1;awk_cmd2;}

    awk -F: 'BEGIN{i=1} {i++} END {print i}' /etc/passwd

BEGIN可以进行数据初始化,END可以进行数据汇总

awk内置变量(预定义变量):

  • $n 当前记录的第n个字段,比如: $1表示第一个字段,$2表示第二个字段
  • $0 这个变量包含执行过程中当前行的文本内容
  • FILENAME 当前输入文件的名
  • FS 字段分隔符(默认是空格)
  • NF 表示字段数,在执行过程中对应于当前的字段数,NF:列的个数
  • FNR  各文件分别计数的行号
  • NR 表示记录数,在执行过程中对应于当前的行号
  • OFS 输出字段分隔符(默认值是一个空格)
  • ORS 输出记录分隔符(默认值是一个换行符)
  • RS 记录分隔符(默认是一个换行符)
  • ARGC 命令行参数个数
  • ARGV 命令行参数排列
  • ENVIRON 输出系统环境变量
  • \t        制表符
  • \n      换行符
  • ~        匹配
  • !~      不匹配
  • -F'[:#/]+'  定义三个分隔符
  • \\ \自身
  • \$ 转义$
  • \b 退格符
  • \r 回车符
  • \c 取消换行

awk内置函数 :

算数函数:sqrt(求平方根)、

rand(当参数缺省的时候,使用当前时间作为随机数种子)、

srand(内置函数rand的伪随机函数,其返回值范围在【0,1】,实际使用时,一般使用srand生成随机数种子,在使用rand函数生成随机数,否则每次的值都一样)。

    [root@manager ~]# awk 'BEGIN{x=sqrt(100);print x}'

    10

    [root@manager ~]# awk 'BEGIN{x=rand();print x}'

    0.237788

    [root@manager ~]# awk 'BEGIN{srand();x=int(100*rand());print x}'

    64

字符串函数:sub和gsub函数(替换符,前者是只替换第一个,后者是替换所有)、

index函数(查找字符)

length函数(计算长度)

substr函数(截取字符串)

match函数(正则匹配查找)

split函数(字符分割)

    [root@manager ~]# awk 'BEGIN{info="this is a

    test2010test2010test!";sub(2010,"!",info);print info}'

    this is a test!test2010test!

    [root@manager ~]# awk 'BEGIN{info="this is a 

    test2010test2010test!";gsub(2010,"!",info);print info}'

    this is a test!test!test!

    [root@manager ~]# awk 'BEGIN{info="this is test2010test!";print 

    index(info,"test")?"ok":"not found";}'

    ok

    [root@manager ~]# awk 'BEGIN{info="hello";print length(info)}'

    5

    [root@manager ~]# awk 'BEGIN{info="hello world";print substr(info,4,10)}'

    lo world

    [root@manager ~]# awk 'BEGIN{info="hello 2016world";print match(info,/[0-

    9]+/)?"ok":"none";}'

    ok

    [root@manager ~]# awk 'BEGIN{info="hello world";split(info,test);print length(test);for(k

    in  test){print k,test[k];}}'

    2

    1 hello

    2 world

一般函数:

close( Expression )

用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的。

system(Command )

执行 Command 参数指定的命令,并返回退出状态。等同于 system 子例程。

Expression | getline [ Variable ]

从来自 Expression 参数指定的命令的输出中通过管道传送的流中读取一个输入记录,并将该记录的值指定给 Variable 参数指定的变量。如果当前未打开将 Expression 参数的值作为其命令名称的流,则创建流。创建的流等同于调用 popen 子例程,此时 Command 参数取 Expression 参数的值且 Mode 参数设置为一个是 r 的值。只要流保留打开且 Expression 参数求得同一个字符串,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。

getline [ Variable ] < Expression

从 Expression 参数指定的文件读取输入的下一个记录,并将 Variable 参数指定的变量设置为该记录的值。只要流保留打开且 Expression 参数对同一个字符串求值,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。

getline [ Variable ]

将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录。如果未指定 Variable 参数,则 $0 记录变量设置为该记录的值,还将设置 NF、NR 和 FNR 特殊变量。

[root@manager ~]# awk 'BEGIN{while("head -5 /etc/passwd"|getline){print $0;};close("/etc/passwd");}'
root:x:0:0:root:/root:/bin/bash
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@manager ~]# awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}'

[root@manager ~]# awk 'BEGIN{print "Enter your name:";getline name;print name;}'
Enter your name:
robin
robin

[root@manager ~]# awk 'BEGIN{b=system("ls -l /root");print b;}'
总用量 20
-rw-r--r-- 1 root root 135 9月 18 16:14 aa.txt
-rw-------. 1 root root 905 9月 9 06:30 anaconda-ks.cfg
-rw-r--r--. 1 root root 8003 9月 9 06:30 install.log
-rw-r--r--. 1 root root 3384 9月 9 06:30 install.log.syslog
0
[root@manager test7]# awk -F: 'BEGIN{x=system("id robin &>/dev/null");if(x==0){while(getline < "/etc/passwd")if($1=="robin")print $1,$6}}'
robin /home/robin

时间函数: 

函数名

说明

mktime( YYYY MM DD HH MM SS[ DST])

生成时间格式

strftime([format [, timestamp]])

格式化时间输出,将时间戳转为时间字符串  具体格式,见下表.

systime()

得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数

[root@manager ~]# awk 'BEGIN{tstamp=mktime("2001 01 01 12 12 12");print strftime("%c",tstamp);}'
2001年01月01日 星期一 12时12分12秒

[root@manager ~]# awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=mktime("2001 02 01 0 0 0");print tstamp2-tstamp1;}'
2634468

[root@manager ~]# awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=systime();print tstamp2-tstamp1;}'
495876393

strftime日期和时间格式说明符:

格式

描述

%a

星期几的缩写(Sun)

%A

星期几的完整写法(Sunday)

%b

月名的缩写(Oct)

%B

月名的完整写法(October)

%c

本地日期和时间

%d

十进制日期

%D

日期 08/20/99

%e

日期,如果只有一位会补上一个空格

%H

用十进制表示24小时格式的小时

%I

用十进制表示12小时格式的小时

%j

从1月1日起一年中的第几天

%m

十进制表示的月份

%M

十进制表示的分钟

%p

12小时表示法(AM/PM)

%S

十进制表示的秒

%U

十进制表示的一年中的第几个星期(星期天作为一个星期的开始)

%w

十进制表示的星期几(星期天是0)

%W

十进制表示的一年中的第几个星期(星期一作为一个星期的开始)

%x

重新设置本地日期(08/20/99)

%X

重新设置本地时间(12:00:00)

%y

两位数字表示的年(99)

%Y

当前月份

%Z

时区(PDT)

%%

百分号(%)

 printf函数:是格式化输出函数,一般用于向标准输出设备按规定格式输出信息

printf()函数的调用格式为:

%d 十进制有符号整数

%u 十进制无符号整数

%f 浮点数

%s 字符串

%c 单个字符

%p 指针的值

%e 指数形式的浮点数

%x, %X 无符号以十六进制表示的整数

%o 无符号以八进制表示的整数

%g 自动选择合适的表示法

\n 换行

\f 清屏并换页

\r 回车

\t Tab符

\xhh 表示一个ASCII码用16进表示,其中hh是1到2个16进制数

输出样式 %s是字符类型,%d数值类型

printf默认是不输出换行的所以要加\n

10和7是偏移量 默认是右对齐,所有加个- 就是左对齐,就是把不足的位数用空格填充

注意:格式与输出列之间要有逗号

[root@manager ~]# awk 'BEGIN{a=16;printf "%-10o\n",a}'

20

常用命令
cat example.txt | awk 'NR%2==1' 	#删除example.txt文件中的所有偶数行
echo "    false" |awk -F' ' '{print $NF}'		#去掉前面的空格
docker images | grep 'mysql' | awk '{printf"%s:%s\n",$1,$2}'	#获取镜像名:Tag
ps -ef | grep java | grep -v 'color' awk '{for (i=8;i<=NF;i++)printf("%s ", $i);print ""}' #获取从第八列开始到最后一列的内容
1
2
3
4

常用技巧
打印各磁盘可用大小
df | grep -v tmpfs | awk 'NR!=1 {disk[$1]=$4} \
END {for(i in disk) {printf "%-20s %-10s\n",i,disk[i]/1024"M"}
}'
1
2
3


统计磁盘可用容量
df | tail -n +2 | grep -v tmpfs | awk '{sum+=$4} END{print "磁盘可用容量:"sum/1024/1024"G"}'
1


统计/etc下文件总大小
ls -l /etc | awk '/^-/{sum+=$5} END{print "文件总大小:"sum/1024"M"}'
1


统计访问Nginx的各IP访问次数
awk ' \
{IP[$1]++} \
END { \
for (i in IP) {print i,IP[i]} \
}' /var/log/nginx/access.log
1
2
3
4
5

查看Nginx 1点到5点半的日志
awk -F"[: /]" '$7":"$8 >= "01:00" && $7":"$8 <="05:30"' /var/log/nginx/access.log
1

查看Docker容器的CPU使用率
docker stats jenkins --no-stream |awk 'NR==2{print $3}'
此部分来自:https://blog.csdn.net/anqixiang/article/details/117903529

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亲爱的老少女

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值