文本三剑客之进阶awk

文本三剑客之进阶awk

一、awk简介

​ awk是一种处理数据、产生格式化报表的语言,功能也是十分强大,awk认为文件中每一行是一条记录,记录与记录的分隔符为换行符,每一列是一个字段,字段与字段分隔符默认是一个空格,或多个空格。

​ awk的工作方式是读取数据,将每一行数据视为一条记录,每条记录以字段分隔符分成若干字段,然后输出各个字段的值。

在这里插入图片描述

# 常用命令选项:
-F fs           指定文件的分隔符 默认为空格
-f file         指定读取程序的文件名
-v var=value    定义awk程序中使用的变量和默认值

# awk程序的优先级:
BEGIN: 在开始处理数据流之前执行 优先级最高  可选项
program: 如何处理数据流 优先级中等 必选项(默认是program)
END: 处理完数据流后执行 优先级最低 可选项
# 内置变量:
$0               表示整行内容
$1               表示一行中 第一个字段
$2               表示一行中 第二个字段(以此类推)
$NF              表示一行中 最后一个字段
$NR              指定行号
$FIELDWIDTHS     自定义列宽
$FS              输入字段分隔符 类似于F
$OFS             输出字段分隔符
$RS				 输入记录分隔符
$ORS             输出记录分隔符

二、awk基本用法

# 演示数据内容:
[root@shell awk]# cat test 
1 the quick for jump over the lazy cat . dog
2 the quick for jump over the lazy cat . dog
3 the quick for      jump over the lazy cat . dog
4 the quick for jump over the lazy cat . dog
5 the quick for jump over the lazy cat . dog
6 the quick for jump over the lazy cat . dog

1、awk对字段(列)的提取

# 1、打印第3个字段值
[root@shell awk]# awk '{print $2}' test 
the
the
the
the
the
the

# 2、打印最后一个字段值
[root@shell awk]# awk '{print $NF}' test 
dog
dog
dog
dog
dog
dog

//使用-F 选项可指定字段分隔符

# 3、指定字段分割符为:
[root@shell awk]# awk -F: '{print $1}' passwd

//-v 定义变量

# 4、定义name变量值为qinziteng  调用name变量
[root@shell awk]# awk -v name='qinziteng' 'BEGIN{print name}'
qinziteng

//除了使用-v定义变量 还可以使用=定义变量 如下:

# 5、使用变量查看内存使用率
[root@shell awk]# cat /proc/meminfo  |head  -3 | awk 'NR==1{n=$2} NR==2{m=$2;print (n-m)*100/n "%" }'
29.3505%

[root@shell awk]# head -3 /proc/meminfo  |awk 'NR==1{t=$2}NR==2{f=$2;m=t-f}END {print m/t*100,"%"}'
29.3208 %

2、awk对记录(行)的提取

使用NR 指定行号

# 1、使用NR内置变量 值打印出第一行 第一个字段
[root@shell awk]# awk  -F:  'NR==1{print $1}' passwd 
root

# 2、打印多个字段
[root@shell awk]# awk  -F:  'NR==1{print $1 $2 $3}' passwd 
rootx0    

//尽管在awk变量与变量直接使用空格相隔开了,输出的值也没用空格的,变量与变量可以使用逗号隔开,输出的值就有空格了,如下:

[root@shell awk]# awk -F: 'NR==1{print $1,$2,$3}' passwd 
root x 0

//还是上面这个例子 如果我想要 root-x-0 这种方式显示处理 该如何操作呢?

只需要使用双引号 引起来即可 如下:

[root@shell awk]# awk -F: 'NR==1{print $1"-" $2"-"$3}' passwd

那如果想要 user:root pwd:x uid:0 这样输出 呢? 如下:

[root@shell awk]# awk -F: 'NR==1{print "user:"$1,"pwd:"$2,"uid:"$3}' passwd 
user:root pwd:x uid:0

3、awk的优先级

BEGIN: 在开始处理数据流之前执行 优先级最高  可选项
program: 如何处理数据流 优先级中等 必选项(默认是program)
END: 处理完数据流后执行 优先级最低 可选项
# 1、BEGIN   使用BEGIN优先级最高 其意思是在处理出数据流之前做什么 不需要指定文件
[root@shell awk]# awk 'BEGIN{print "qinziteng"}'
qinziteng

# 2、program 默认就是program 需要指定文件
[root@shell awk]# awk -F: 'NR==1{print $1}' passwd 
root

# 3、END  使用END优先级最低   其意思是在处理完成数据流之后做什么 不需要指定文件
[root@shell awk]# awk -F: 'NR==1{print $1}END{print $2}' passwd 
root
x

# 4、三个连接起来一起使用
[root@shell awk]# awk -F: ' BEGIN{print "start"} {print $1}END{print "stop"}' passwd 

三、awk高级用法

awk是一门语言,那么就符合语言的特性,除了可以定义变量之外,还可以定义数组、进行运算、流程控制等。

1、定义数组

语法格式:

数组名称[索引]=
# 2、定义数组
[root@shell awk]# awk 'BEGIN{array[0]=100;array[1]=200;print array[0],array[1]}' 
100 200

2、awk运算

1)赋值运算

=           赋值运算
[root@shell awk]# awk 'BEGIN{a=qin;print "qin"}'
qin

2)比较运算

#比较运算,如果比较的是字符串则按asci编码顺序比较。返回值=1则为真,返回值=0则为假
>          大于
>=         大于等于
<          小于
<=         小于等于
==         等于
!=         不等于
# a等于b
[root@shell awk]# awk 'BEGIN{print "a" == "b"}'
0

[root@shell awk]# awk 'BEGIN{print "a" != "b"}'
1

[root@shell awk]# seq 1 10 >num
#打印出$1大于5
[root@shell awk]# awk '$1>5{print $0}' num 
6
7
8
9
10

#打印出$1小于5
[root@shell awk]# awk '$1<5{print $0}' num 
1
2
3
4

3)数学运算

+         加
-         减
*         乘
/         除
%         求余
**        开方
++        加1
--        减1
# 除
[root@shell awk]# awk 'BEGIN{print 100/3 }'
33.3333

# 100的3次方
[root@shell awk]# awk 'BEGIN{print 100**3 }'
1000000

# ++ 和 --
[root@shell awk]# awk 'BEGIN{count=1;count++;print count}'
2
[root@shell awk]# awk 'BEGIN{count=1;count--;print count}'
0

4)逻辑运算

&&        逻辑与     真真为真  真假为假  假假为假
||        逻辑或     真真为真  真假为真  假假为假
[root@shell awk]# awk 'BEGIN{print 100>=2 && 100>=101 }'
0

[root@shell awk]# awk 'BEGIN{print 100>=2 || 100>=101 }'
1

5)匹配运算

精确匹配:
==
!=
模糊匹配:
~
!~

精确匹配:

# 匹配root
[root@shell awk]# awk -F: '$1=="root"{print $0}' passwd 
root:x:0:0:root:/root:/bin/bash
# 精确不匹配 取反
[root@shell awk]# awk -F: '$1!="root"{print $0}' passwd 

模糊匹配:

# 模糊匹配
[root@shell awk]# awk -F: '$1 ~ "r"{print $0}' passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
# 模糊不匹配 取反
[root@shell awk]# awk -F: '$1 !~ "r"{print $0}' passwd 

3、awk内置变量

$FIELDWIDTHS     自定义列宽
$FS              输入字段分隔符 类似于F
$OFS             输出字段分隔符
$RS				 输入记录分隔符   默认是回车
$ORS             输出记录分隔符
# 自定义列宽 要求第一个$1 三个字符  $2 二个字符  $NF 5个字符
[root@shell awk]# awk -F: 'BEGIN{FIELDWIDTHS="3 2 5"}NR==1{print $1,$2,$NF}' passwd 
roo t: x:0:0

# 指定输入分隔符
[root@shell awk]# awk 'BEGIN{FS=":"}$1=="root"{print $1,$3,$5}' passwd 
root 0 root

# 指定输出分隔符 
[root@shell awk]# awk 'BEGIN{FS=":";OFS="-"}$1=="root"{print $1,$3,$5}' passwd 
root-0-root

# 指定记录输入分隔符为空
[root@shell awk]# awk 'BEGIN{RS=""}{print $1,$2,$3}' num 
1 2 3

# 指定记录输出分隔符为###(默认是回车,这里定义为### 所以就没有了回车了)
[root@shell awk]# awk 'BEGIN{RS="";ORS="###"}{print $1,$2,$3}' num 
1 2 3###[root@shell awk]# 

四、awk流程控制

1、if语句

[root@shell awk]# cat num 
1
2
3
4
5
6
7
8
9
10

1)单if

# 打印出$1大于5的数字
[root@shell awk]# awk '{if($1>5)print $0}' num 
6
7
8
9
10

2)if…else

[root@shell awk]# awk '{
if ($1<5)
  print $1*2
else
  print $1/2
}' num
2
4
6
8
2.5
3
3.5
4
4.5
5

#写成一行的格式 注意eles前有个分号";"
[root@shell awk]# awk '{if ($1>5)print $1+2;else print $1-2 }' num 
-1
0
1
2
3
8
9
10
11
12

2、for循环

[root@shell awk]# cat num2 
60 50 100
150 30 10
70 100 40
# 列的累加
[root@shell awk]# awk -v 'sum=0' '{sum+=$1}END{print sum}' num
55

# 行的累加
[root@shell awk]# awk '{sum=0;for (i=1;i<4;i++){sum+=$i}print sum}' num2 
210
190
210

五、awk小技巧

# 打印文本行数
[root@shell awk]# awk 'END{print NR}' passwd 
25

# 打印最后一行内容
[root@shell awk]# awk 'END{print $0}' passwd 
nginx:x:998:1002::/home/nginx:/sbin/nologin


# 打印文本有多少列
[root@shell awk]# awk  -F: 'END{print NF}' passwd 
7
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

神奇的海马体

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

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

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

打赏作者

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

抵扣说明:

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

余额充值