三剑客之 sed

简介: 三剑客之 sed

AWK是贝尔实验室1977年搞出来的文本出现神器

之所以叫AWK是因为其取了三位创始人 Alfred AhoPeter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符

今天这篇文章主要目的还是为了引起大家对 awk 的兴趣,对于这个上古神器还需要大家自行去查阅相关文档去进一步学习

通常,awk 是以文件的一行为处理单位的,awk 每接受文件的一行,就会执行相应的命令来处理文本

例如:执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令

awk '{print 1 $0}' /etc/passwd

image-20221112093917261.png

1. 过滤

从 netstat 命令中提取了以下信息作为例子
image-20221112093348755.png

Proto Recv-Q Send-Q Local-Address          Foreign-Address              State
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                    LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                    LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                    LISTEN
tcp        0      0 saltedfish.cn:80        124.205.5.146:18245         TIME_WAIT
tcp        0      0 saltedfish.cn:80        61.140.101.185:37538        FIN_WAIT2
tcp        0      0 saltedfish.cn:80        110.194.134.189:1032        ESTABLISHED
tcp        0      0 saltedfish.cn:80        123.169.124.111:49809       ESTABLISHED
tcp        0      0 saltedfish.cn:80        116.234.127.77:11502        FIN_WAIT2
tcp        0      0 saltedfish.cn:80        123.169.124.111:49829       ESTABLISHED
tcp        0      0 saltedfish.cn:80        183.60.215.36:36970         TIME_WAIT
tcp        0   4166 saltedfish.cn:80        61.148.242.38:30901         ESTABLISHED
tcp        0      1 saltedfish.cn:80        124.152.181.209:26825       FIN_WAIT1
tcp        0      0 saltedfish.cn:80        110.194.134.189:4796        ESTABLISHED
tcp        0      0 saltedfish.cn:80        183.60.212.163:51082        TIME_WAIT
tcp        0      1 saltedfish.cn:80        208.115.113.92:50601        LAST_ACK
tcp        0      0 saltedfish.cn:80        123.169.124.111:49840       ESTABLISHED
tcp        0      0 saltedfish.cn:80        117.136.20.85:50025         FIN_WAIT2
tcp        0      0 :::22                  :::*                        LISTEN

比如说我们想输出例子中的第一列和第四列

  • $n:表示第几列($0表示整个内容)
  • 执行的操作只能是单引号
awk '{print $1, $4}' test.txt
Proto Local-Address
tcp 0.0.0.0:3306
tcp 0.0.0.0:80
tcp 127.0.0.1:9000
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp saltedfish.cn:80
tcp :::22

加上过滤条件

1、过滤条件:第一列的值为 tcp && 第六列的值为 LISTEN

awk '$1=="tcp" && $6=="LISTEN"' test.txt

2、过滤条件:第三列的值大于等于1,打印过滤出的内容

awk '$3>=1 {print$0}' test.txt

常用的比较运算符

==:等于
!=:不等于
>:大于
<: 
>=:
<=:

指定分隔符

  • 默认是以空格作为分隔符
  • -F 参数:指分隔符

1、以空格作为分隔符,打印出第四列内容

awk '{print $4}' test.txt
或者
awk -F ' ' '{print $4}' test.txt
Local-Address
0.0.0.0:3306
0.0.0.0:80
127.0.0.1:9000
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
saltedfish.cn:80
:::22

2、以 “:” 作为分隔符,打印出第二列内容

awk -F ':' '{print $2}' test.txt
3306           0.0.0.0
80             0.0.0.0
9000         0.0.0.0
80        124.205.5.146
80        61.140.101.185
80        110.194.134.189
80        123.169.124.111
80        116.234.127.77
80        123.169.124.111
80        183.60.215.36
80        61.148.242.38
80        124.152.181.209
80        110.194.134.189
80        183.60.212.163
80        208.115.113.92
80        123.169.124.111
80        117.136.20.85

3、如果要指定多个分隔符,可以这样:

awk -F '[;:]'

2. awk 内置变量

$0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列
NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字

1、我们对输出结果加上行号(过滤条件:第三列的值大于1)

awk '$3>=1 {print NR,$0}' test.txt
1 $ cat netstat.txt
2 Proto Recv-Q Send-Q Local-Address          Foreign-Address             State
13 tcp        0   4166 saltedfish.cn:80        61.148.242.38:30901         ESTABLISHED
14 tcp        0      1 saltedfish.cn:80        124.152.181.209:26825       FIN_WAIT1
17 tcp        0      1 saltedfish.cn:80        208.115.113.92:50601        LAST_ACK

2、忽略第一行(即 NR>1)

awk '$3>=1 && NR>1 {print NR,$0}' test.txt
2 Proto Recv-Q Send-Q Local-Address          Foreign-Address             State
13 tcp        0   4166 saltedfish.cn:80        61.148.242.38:30901         ESTABLISHED
14 tcp        0      1 saltedfish.cn:80        124.152.181.209:26825       FIN_WAIT1
17 tcp        0      1 saltedfish.cn:80        208.115.113.92:50601        LAST_ACK

3、输出字段以 tab 分隔(以 /etc/passwd 为例)

字段分隔符默认是空格

awk -F ':' '{print $1,$3} ' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
chrony 998
tss 59
ntp 38
tcpdump 72
zabbix 997
minion2 1000
nginx 996

指定为 tab

awk -F ':' '{print $1,$3} ' OFS='\t' /etc/passwd
root    0
bin     1
daemon  2
adm     3
lp      4
sync    5
shutdown        6
halt    7
mail    8
operator        11
games   12
ftp     14
nobody  99
systemd-network 192
dbus    81
polkitd 999
sshd    74
postfix 89
chrony  998
tss     59
ntp     38
tcpdump 72
zabbix  997
minion2 1000
nginx   996

4、输出记录以 tab 分隔(以 /etc/passwd 为例)

记录(行)分隔符默认是换行符

awk -F ':' '{print $1,$3} '  /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
chrony 998
tss 59
ntp 38
tcpdump 72
zabbix 997
minion2 1000
nginx 996

指定为 tab

awk -F ':' '{print $1,$3} ' ORS="\t" /etc/passwd
root 0  bin 1   daemon 2        adm 3   lp 4    sync 5  shutdown 6      halt 7  mail 8  operator 11     games 12        ftp 14  nobody 99 systemd-network 192      dbus 81 polkitd 999     sshd 74 postfix 89      chrony 998      tss 59  ntp 38  tcpdump 72      zabbix 997      minion2 1000       nginx 996

3.正则

image-20221112133539744.png
字符串匹配

~ 表示模式开始、/ /中是模式。这就是一个正则表达式的匹配

1、匹配 LISTEN

awk '$6 ~ /LISTEN/ {print $0}' test.txt
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                   LISTEN
tcp        0      0 :::22                  :::*                        LISTEN

2、支持模糊匹配

匹配 LIS 的话,LISTEN 和 EATABLISTED 都会输出

awk '$6 ~ /LIS/ {print $0}' test.txt
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                   LISTEN
tcp        0      0 saltedfish.cn:80        110.194.134.189:1032        ESTABLISHED
tcp        0      0 saltedfish.cn:80        123.169.124.111:49809       ESTABLISHED
tcp        0      0 saltedfish.cn:80        123.169.124.111:49829       ESTABLISHED
tcp        0   4166 saltedfish.cn:80        61.148.242.38:30901         ESTABLISHED
tcp        0      0 saltedfish.cn:80        110.194.134.189:4796        ESTABLISHED
tcp        0      0 saltedfish.cn:80        123.169.124.111:49840       ESTABLISHED
tcp        0      0 :::22                  :::*                        LISTEN

3、多个匹配条件

awk '$6 ~ /LISTEN|FIN/{print $0}' test.txt
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                   LISTEN
tcp        0      0 saltedfish.cn:80        61.140.101.185:37538        FIN_WAIT2
tcp        0      0 saltedfish.cn:80        116.234.127.77:11502        FIN_WAIT2
tcp        0      1 saltedfish.cn:80        124.152.181.209:26825       FIN_WAIT1
tcp        0      0 saltedfish.cn:80        117.136.20.85:50025         FIN_WAIT2
tcp        0      0 :::22                  :::*                        LISTEN

4、取反匹配

awk '$6 !~ /LISTEN|FIN/ {print $0}' test.txt
$ cat netstat.txt
Proto Recv-Q Send-Q Local-Address          Foreign-Address             State
tcp        0      0 saltedfish.cn:80        124.205.5.146:18245         TIME_WAIT
tcp        0      0 saltedfish.cn:80        110.194.134.189:1032        ESTABLISHED
tcp        0      0 saltedfish.cn:80        123.169.124.111:49809       ESTABLISHED
tcp        0      0 saltedfish.cn:80        123.169.124.111:49829       ESTABLISHED
tcp        0      0 saltedfish.cn:80        183.60.215.36:36970         TIME_WAIT
tcp        0   4166 saltedfish.cn:80        61.148.242.38:30901         ESTABLISHED
tcp        0      0 saltedfish.cn:80        110.194.134.189:4796        ESTABLISHED
tcp        0      0 saltedfish.cn:80        183.60.212.163:51082        TIME_WAIT
tcp        0      1 saltedfish.cn:80        208.115.113.92:50601        LAST_ACK
tcp        0      0 saltedfish.cn:80        123.169.124.111:49840       ESTABLISHED

4.BEGIN & END

BEGIN 和 END 这两个关键字意味着执行前和执行后的意思,语法如下:

  • BEGIN{ 这里面放的是执行前的语句 }
  • END {这里面放的是处理完所有的行后要执行的语句 }
  • {这里面放的是处理每一行时要执行的语句}

以下面内容为例(将 top 输出结果重定向到 top.txt 中)

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.1 125636  4148 ?        Ss   11月11   0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    11月11   0:00 [kthreadd]
root          4  0.0  0.0      0     0 ?        S<   11月11   0:00 [kworker/0:0H]
root          6  0.0  0.0      0     0 ?        S    11月11   0:00 [ksoftirqd/0]
root          7  0.0  0.0      0     0 ?        S    11月11   0:00 [migration/0]
root          8  0.0  0.0      0     0 ?        S    11月11   0:00 [rcu_bh]
root          9  0.0  0.0      0     0 ?        R    11月11   0:07 [rcu_sched]
root         10  0.0  0.0      0     0 ?        S<   11月11   0:00 [lru-add-drain]
root         11  0.0  0.0      0     0 ?        S    11月11   0:00 [watchdog/0]
root         12  0.0  0.0      0     0 ?        S    11月11   0:00 [watchdog/1]
root         13  0.0  0.0      0     0 ?        S    11月11   0:00 [migration/1]
root         14  0.0  0.0      0     0 ?        S    11月11   0:00 [ksoftirqd/1]
root         16  0.0  0.0      0     0 ?        S<   11月11   0:00 [kworker/1:0H]
root         18  0.0  0.0      0     0 ?        S    11月11   0:00 [kdevtmpfs]
root         19  0.0  0.0      0     0 ?        S<   11月11   0:00 [netns]
root         20  0.0  0.0      0     0 ?        S    11月11   0:00 [khungtaskd]
root         21  0.0  0.0      0     0 ?        S<   11月11   0:00 [writeback]
root         22  0.0  0.0      0     0 ?        S<   11月11   0:00 [kintegrityd]
root         23  0.0  0.0      0     0 ?        S<   11月11   0:00 [bioset]
root         24  0.0  0.0      0     0 ?        S<   11月11   0:00 [bioset]
root         25  0.0  0.0      0     0 ?        S<   11月11   0:00 [bioset]
root         26  0.0  0.0      0     0 ?        S<   11月11   0:00 [kblockd]
root         27  0.0  0.0      0     0 ?        S<   11月11   0:00 [md]
root         28  0.0  0.0      0     0 ?        S<   11月11   0:00 [edac-poller]
root         29  0.0  0.0      0     0 ?        S<   11月11   0:00 [watchdogd]
root         35  0.0  0.0      0     0 ?        S    11月11   0:00 [kswapd0]
root         36  0.0  0.0      0     0 ?        SN   11月11   0:00 [ksmd]
root         37  0.0  0.0      0     0 ?        SN   11月11   0:00 [khugepaged]
root         38  0.0  0.0      0     0 ?        S<   11月11   0:00 [crypto]
root         46  0.0  0.0      0     0 ?        S<   11月11   0:00 [kthrotld]
root         49  0.0  0.0      0     0 ?        S<   11月11   0:00 [kmpath_rdacd]
root         50  0.0  0.0      0     0 ?        S<   11月11   0:00 [kaluad]
root         51  0.0  0.0      0     0 ?        S<   11月11   0:00 [kpsmoused]
root         53  0.0  0.0      0     0 ?        S<   11月11   0:00 [ipv6_addrconf]
root         66  0.0  0.0      0     0 ?        S<   11月11   0:00 [deferwq]
root        104  0.0  0.0      0     0 ?        S    11月11   0:00 [kauditd]
root        283  0.0  0.0      0     0 ?        S<   11月11   0:00 [mpt_poll_0]

1、计算每个用户的进程占了多少内存

awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}' top.txt
chrony, 1860KB
nginx, 3688KB
dbus, 2492KB
polkitd, 14152KB
root, 208636KB

2、统计当前目录下文件所占空间大小

ll -h | awk 'BEGIN {size=0} {size=size+$5} END{print size "KB"}'

3、统计 /etc/passwd 中用户数量

awk '{count++} END{print count}' /etc/passwd

4、统计有多少条 tcp 连接

(减掉 2 是因为前面两条字段不是 tcp 连接)
image-20221112140427841.png

netstat -tnlp | awk '{count++} END{print count-2}'

5、打印出 11日到12日 13点到14点之间的日志信息

image-20221112141221666.png

awk '{if ($2>10 && $2<12 && $3>"13:00:00" && $3<"14:00:00") print}' /var/log/messages
相关文章
|
安全 网络协议 网络安全
网安面试指南——(渗透,攻击,防御)
网安面试指南——(渗透,攻击,防御)
303 2
|
算法 Android开发
LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
141 1
|
Prometheus Cloud Native 数据可视化
Istio可观测性
Istio可观测性
280 2
|
10月前
|
人工智能 自然语言处理 开发者
开源上新 | 通义音乐生成技术InspireMusic
开源上新 | 通义音乐生成技术InspireMusic
|
SQL 分布式计算 Java
阿里云web应用
设备端将图片编码为base64发送至物联网平台,在web界面配置图片选择物联网平台配置的数据(base64),实现设备向云平台的图片的上传,以及在web界面上显示图片。
|
存储 Java
Java的接口、类、属性、方法的修饰符使用总结
Java的接口、类、属性、方法的修饰符使用总结
825 0
|
SQL Oracle 关系型数据库
ORACLE错误码及解决方法
ORACLE错误码及解决方法
1017 0
|
关系型数据库 分布式数据库 数据库
PolarDB常见问题之PolarDB影响下游的binlogl同步如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
前端开发 JavaScript
jquery+css实现Tab栏切换的代码实例
jquery+css实现Tab栏切换的代码实例
217 0