19.三剑客之awk

awk:格式化文本输出
awk是逐行处理的,逐行处理的意思就是说,当awk处理一个文本时,会一行一行进行处理,处理完当前行,再处理下一行,awk默认以"换行符"为标记,识别每一行,也就是说,awk跟我们人类一样,每次遇到"回车换行",就认为是当前行的结束,新的一行的开始,awk会按照用户指定的分割符去分割当前行,如果没有指定分割符,默认使用空格或者tab键作为分隔符。

基本用法:
awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{ action;… }’ file …
awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块,共3部分组成
program通常是被单引号或双引号中

常用选项
-F:指定分隔符
-v:后面带变量
-f:引用program脚本

字段
把每一行用指定的分隔符隔开,每一小段就称为一个字段。
$1:表示第一个字段
$N:表示第N个字段
$NF:表示最后一个字段
$(NF-1):表示倒数第二个字段

记录
1.平时不指定记录分隔符的话,默认每一行就是一条记录。我们也可以指定记录分隔符。
2.RS:可以定义一条记录的分隔符,默认是\n
3.记录不一定是在同一行的,也有有可能跨多行
4.通常不会指定分隔符,都是以一行作为一条记录,了解一下即可

例子:
[root@centos7_101 data]#cat temp.txt
1,2,3;A,B,C;a,b,c 如果以";“作为记录分隔符的话,这一行有3条记录。
[root@centos7_101 data]#awk -v FS=”," -v RS=";" ‘{print $1,$2}’ ./temp.txt
1 2
A B
a b

变量
变量:分为内置和自定义变量。

常见变量:
FS:输入字段分隔符,默认为空白字符
OFS:输出字段分隔符,默认为空白字符
RS:输入记录分隔符,指定输入时的换行符
ORS:输出记录分隔符,输出时用指定符号代替换行符
NF:字段数量
NR:记录号
FNR:各文件分别计数,记录号
FILENAME:当前文件名

例子:
1.如果是awk内变量,直接写上变量名即可
#awk -v FS=":" ‘{print $1FS$4}’ /etc/passwd

2.也可以引用shell中的变量,KaTeX parse error: Expected 'EOF', got '#' at position 5: var #̲fs=:;awk -v FS=fs ‘{print $1FS$4}’ /etc/passwd

3.指定输出分隔符为tab键:\t
#awk -v FS=":" -v OFS="\t" ‘{print $1,$4}’ /etc/passwd

自定义变量
1.格式:-v var=" "
2.直接在program内定义

例子:
#awk -F":" -v USER=“username” -v UID=“userid” ‘{print USER":"$1,UID":"$3}’ /etc/passwd

另一中写法:
#awk -F":" ‘{USER=“username”;UID=“userid”;print USER":"$1,UID":"$3}’ /etc/passwd

printf格式化打印
定义格式化输出。
格式化输出:printf “FORMAT”, 字段1, 字段2, …
(1) 必须指定FORMAT
(2) 不会自动换行,需要显式给出换行控制符,\n

FORMAT中需要分别为后面每个字段指定格式符
格式符:与字段一一对应
%c: 显示字符的ASCII码
%d, %i: 显示十进制整数
%e, %E:显示科学计数法数值
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
:显示字符串
%u:无符号整数
%%: 显示%自身

修饰符:
#[.#]:第一个数字控制显示的总宽度;第二个#表示小数点位数,没有四舍五入:%3.1f
-: 左对齐(默认右对齐) %-15s
+:显示数值的正负符号 %+d

同时使用多个分隔符
1.下例使用"空格 和 :“作为分隔符
[root@centos7_101 data]#echo “a:c b;1:2 3” |awk -v RS=”;" -F"[ :]" ‘{print $1,$2,$3}’
a c b
1 2 3

2.一个或者多个空格和%作为分隔符
[root@centos7_101 ~]#df | awk -F" +|%" ‘/^/dev/sda/{print $1,$5}’
/dev/sda2 21
/dev/sda5 1
/dev/sda1 17

例子:
1.-表示左对齐
#awk -F":" ‘{printf “%-30s %-10d\n”,$1,$3}’ /etc/passwd

操作符
1.算术操作符:
x+y, x-y, x*y, x/y, x^y, x%y

  • x:转换为负数
    +x:将字符串转换为数值

2.字符串操作符:没有符号的操作符,字符串连接
赋值操作符:
=, +=, -=, *=, /=, %=, ^=,++, –

例子:
•awk ‘BEGIN{i=0;print ++i,i}’:先运算加1,再打印
•awk ‘BEGIN{i=0;print i++,i}’:先打印,再运算加1

3.比较操作符:
==, !=, >, >=, <, <=
例子:
[root@centos7_101 ~]#awk -F: ‘$3==0{print $0}’ /etc/passwd
root❌0:0:root:/root:/bin/bash

[root@centos7_101 ~]#awk -F: ‘$3>=1000{print $0}’ /etc/passwd
nfsnobody❌65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
chen❌1000:1000:chen:/home/chen:/bin/bash
bash❌1001:1002::/home/test:/bin/bash

==和=的区别
#awk -F: ‘$3==1{print $0}’ /etc/passwd :这个查询$3的值等于1的行
#awk -F: ‘$3=1{print $0}’ /etc/passwd:这个是把所有$3的值赋值等于1

4.模式匹配符:
~:左边是否和右边匹配包含 !~:是否不匹配
匹配内容用//,//内可以使用正则表达式
例子:
[root@centos7_101 ~]#awk -F: ‘$0~/root/{print $1}’ /etc/passwd
root
operator

[root@centos7_101 ~]#awk -F: ‘/bash$/{print $0}’ /etc/passwd
root❌0:0:root:/root:/bin/bash
chen❌1000:1000:chen:/home/chen:/bin/bash
bash❌1001:1002::/home/test:/bin/bash

5.逻辑操作符
与&&:条件同时满足
或||:其他一个条件满足即可
非!:条件结果取反

例子:
[root@centos7_101 ~]#awk -F: ‘$3>=0 && $3 <=100{print $1}’ /etc/passwd
[root@centos7_101 ~]#awk -F: ‘$3==0 || $3>=1000{print $1}’ /etc/passwd

下面2两种等价
[root@centos7_101 ~]#awk -F: ‘!($3==0){print $1}’ /etc/passwd
[root@centos7_101 ~]#awk -F: ‘$3!=0{print $1}’ /etc/passwd

取反操作
[root@centos7_101 ~]#awk -F: ‘$3>=500{print $1}’ /etc/passwd
[root@centos7_101 ~]#awk -F: ‘!($3>=500){print $1}’ /etc/passwd

6.条件表达式(三目表达式)
selector?if-true-expression:if-false-expression
A?B:C–表示A为真,执行B,A为假,执行C
例子:
[root@centos7_101 ~]#awk -F: ‘{$3>=1000?usertype=“Common User”:usertype=“SysUser”;printf “%30s:%-s\n”,$1,usertype }’ /etc/passwd

awk的PATTERN
PATTERN:根据pattern条件,过滤匹配的行,再做处理
(1)如果未指定:空模式,匹配每一行
(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来

例子:
awk ‘/^UUID/{print $1}’ /etc/fstab
awk ‘!/^UUID/{print $1}’ /etc/fstab

统计连接IP数
[root@centos7_101 ~]#netstat -nt | awk -F" +|:" ‘/^tcp/{print $6}’ | sort |uniq -c |sort -rn
3 172.20.34.100
1 172.20.34.102

指定某一行匹配正则表达式
[root@centos7_101 data]#awk -F: ‘ N F   / b a s h NF ~ /bash NF /bash/{print 1 , 1, 1,NF}’ /etc/passwd

(3) relational expression: 关系表达式,结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值

例子:
[root@centos7_101 data]#awk –F: ‘$3>=1000{print $1,$3}’ /etc/passwd
[root@centos7_101 data]#awk -F: ‘$3<1000{print $1,KaTeX parse error: Expected 'EOF', got '}' at position 2: 3}̲' /etc/passwd […NF=="/bin/bash"{print 1 , 1, 1,NF}’ /etc/passwd

(4) line ranges:行范围
startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式

例子:
[root@centos7_101 data]#awk -F: ‘/root>/,/nobody>/{print $1}’ /etc/passwd
[root@centos7_101 data]#awk -F: ‘(NR>=10&&NR<=20){print NR,$1}’ /etc/passwd
[root@centos7_101 data]#awk -F: ‘/b/,/f/’ /etc/passwd

(5) BEGIN/END模式
格式:‘BEGIN{ action;… } pattern{ action;… } END{ action;… }’
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次

例子:
[root@centos7_101 data]#awk -F: ‘BEGIN{print “USER USERID”}{print $1":"$3}END{print “end file”}’ /etc/passwd

[root@centos7_101 data]#awk -F: ‘{print “USER USERID”;print $1":"$3} END{print “end file”}’ /etc/passwd

[root@centos7_101 data]#awk -F: ‘BEGIN{print “USER UID \n----------”}END{print “USER UID\n==========”}’ /etc/passwd

[root@centos7_101 data]#seq 10 | awk ‘i=!i’
1
3
5
7
9
[root@centos7_101 data]#seq 10 | awk -v i=1 ‘i=!i’
2
4
6
8
10

等价于:
#seq 10 | sed -n ‘1~2p’
#seq 10 | sed -n ‘2~2p’
#seq 1 2 10

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值