(八)学习笔记:sed、awk基本用法

1.sed的命令解析

1.1.Stream EDitor 流式编辑器

特点:
— 非交互,基于模式匹配过滤及修改文本
— 逐行处理,并将结果输出到屏幕
— 可实现对文本的输出、删除、替换、复制、剪切、导入、导出等各种操作

1.2.sed命令解析

基本用法:
— 格式1:前置命令 | sed 选项 ‘条件指令’
— 格式2:sed 选项 ‘条件指令’ 文件…

相关说明如下:
条件可以是行号或者正则
没有条件时,默认为所有行
指令可以是增、删、改、查等指令
默认sed会将所有输出的内容都打印出来,可以使用 –n 屏蔽默认输出
选项中可以使用 –r 选项,让sed支持扩展正则
常用选项
-n 屏蔽默认输出(全部文本)
-i 直接修改文件内容
-r 启用扩展正则表达式,若与其他选项一起使用,应作为首个选项

1.3.sed的常用命令

在这里插入图片描述

1.4.sed命令解析/输出指令

1.输出指令
条件可以是行号或/正则
行号可以使用单个数字表示单行
或者3,5表示连续的多行
省略条件则默认逐行处理全部文件
匹配正则时,需要使用//

sed -n 'p' /etc/passwd			#输出所有
sed -n '3p' /etc/passwd			#输出第三行
sed -n '1,4p' /etc/passwd		#输出1-4行
sed -n '4,+10p' /etc/passwd		#输出第四行以及后边的10行内容
sed -n '/^root/p' /etc/passwd	#输出以root开头的行
sed -n '$=' /etc/passwd			#输出文件总行数

2.删除指令
删除文本 —— 指令 d
此案例中只作输出,不更改原文件,若要更改原文件应添加-i 选项
sed ‘1,3d’ 1.txt #删除第1-3行
sed ‘/acb/d’ 1.txt #删除所有包含acb的行
sed ‘/aaa/!d’ 1.txt #删除不包含aaa的行
sed ‘/^abc/d’ 1.txt #删除以abc开头的行
sed ‘KaTeX parse error: Expected 'EOF', got '#' at position 13: d’ 1.txt #̲删除文件最后一行 sed ‘/…/d’ 1.txt #删除所有空行

3.替换指令
替换文本 —— 指令 s
此案例中只作输出,不更改原文件,若要更改原文件应添加-i 选项
sed ‘s/aa/bb/’ 1.txt #将每行中的第一个aa替换为bb
sed ‘s/aa/bb/3’ 1.txt #将每行中的第三个aa替换为bb
sed ‘s/aa/bb/g’ 1.txt #将所有的aa都替换为bb
sed ‘s/aa//g’ 1.txt #将所有的aa替换为空值(相当于删除)
sed -n‘s/aa/bb/p’ 1.txt #只打印替换的内容
sed -n ‘1,7s/^/#/p’ 1.txt #批量给1-7行添加注释(s 前边可以指定行号)
sed -n ‘1,7s/^#//p 1.txt #批量给1-7行注释去掉
注意:替换操作符的分隔符 “/”可以改用其他的分隔符,如 # ,& 等,便于修改文件路径
[root@test opt]# sed -n 's#/bin/bash#/sbin/sh#p’ /etc/passwd

4.导入导出功能
基本动作
r 动作应结合 –I 选项才会存入,否则只会输出
w 动作以覆盖的方式另存为新文件
在这里插入图片描述
r 动作应结合 –I 选项才会存入,否则只会输出
将b.txt文件内容导入到test.txt文件里每一行的下边
[root@test opt]# sed ‘r b.txt’ test.txt

将b.txt文件内容导入到test.txt文件第2行下边
[root@test opt]# sed ‘2r b.txt’ test.txt

将b.txt文件内容导入到test.txt文件1-3行每一行的下边
[root@test opt]# sed ‘1,3r b.txt’ test.txt

w 动作以覆盖的方式另存为新文件
将b.txt文件所有内容导出另存为c.txt文件里,c.txt文件没有可自动创建
[root@test opt]# sed ‘w c.txt’ b.txt

将b.txt文件第2行内容导出另存为c.txt文件里,原有的内容将被覆盖
[root@test opt]# sed ‘2w c.txt’ b.txt

2.awk的命令解析

2.1.awk概括

awk编程语言/数据处理引擎
创造者:Aho Wwinberger Kernighan
基于模式匹配检查输入文本,逐行处理并输出
通常用在shell中,获取指定的数据
单独使用时,可对文本数据做统计

2.2.awk命令格式

主要用法
格式1:前置命令 | awk 选项 ‘条件{指令}’
格式2:awk 选项 ‘条件{指令}’文件… …
其中print是最常用的编辑指令,若有多条指令用分号 ;分隔
awk过滤数据时支持仅打印某一列,如第2列、第4列等
处理文件时,若未指定分隔符,则默认将空格、制表符(tab键)等作为分隔符
[root@test ~]# df -h | awk '{print $4}’
[root@test ~]# awk ‘{print $1,$4}’ 文件

常用命令选项
-F 指定分隔符,如不指定分隔符默认以空格或tab为默认分隔符
示例:过滤passwd文件中以分号为分隔符,打印第1列,第3列
[root@test ~]# awk -F: ‘{print $1,$3}’ /etc/passwd
root 0
bin 1
daemon 2
… …
[root@test opt]# awk -F: ‘{print $1,$7}’ /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
… …
通过awk检查内存的剩余容量
[root@test ~]# free | awk '/Mem/ {print $4}’

通过awk过滤网卡入口流量
[root@test ~]# ifconfig ens160 | awk '/RX p/ {print $5}’

通过awk过滤网卡出口流量
[root@test ~]# ifconfig ens160 | awk ‘/TX p/{print $5}’

awk还识别多种单个的字符,比如以“:”或“/”分隔
指定多个分隔符:以“:”或“/”为分隔符,打印用户名字段,解释器字段

[root@test ~]# head -1 /etc/passwd
root❌0:0:root:/root:/bin/bash

[root@test ~]# awk -F[😕] ‘{print $1,$10}’ /etc/passwd
root bash
bin nologin
daemon nologin
adm sbin
… …

2.3.awk内置变量

awk内置变量
$1 文件第一列
$2 文件第二列
$3 文件第三列,依此类推
NR 文件当前的行号
NF 文件当前行的列数

以 “:”为分隔,输出文件每一行的行号、列数
[root@test ~]# awk -F: ‘{print NR,NF}’ /etc/passwd
1 7
2 7
… …

[root@test ~]# awk -F: ‘{print $1,“用户的解释器为”,$7}’ /etc/passwd

练习1:
利用awk过滤网卡流量信息
#!/bin/bash
while :
do
clear
ifconfig ens160 | awk ‘/inet /{print $2}’ #打印网卡ip列数
ifconfig ens160 | awk ‘/RX p/{print $5}’ #打印网卡入口流量列数
ifconfig ens160 | awk ‘/TX p/{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 5}̲’ #打印网卡出口流量列数 s…/{print “根分区剩余:”,$4}’
free -h | awk ‘/Mem/{print “内存剩余:”,$4}’

2.3.awk过滤时机

awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及处理完最后一行之后做一些总结性质的工作

awk 选项 ‘BEGIN{指令} {指令} END{指令}’ 文件

— BEGIN{} 行前处理,读取文件内容前执行,指令执行1此
— {} 逐行处理,读取文件过程中执行,指令执行n次
— END{} 行后处理,读取文件结束后执行,指令执行1次

练习3:
只做预处理时,可以没有操作的文件
打印常量
[root@test ~]# awk ‘BEGIN{print “正在处理中”}’
正在处理中

打印变量
[root@test ~]# awk 'BEGIN{x=10;print x}’
10
[root@test ~]# awk ‘BEGIN{x=10; print x+5}’
15

练习4:

通过awk统计系统中使用bash作为登录shell的用户总个数
实现思路:

  1. 预处理时赋值变量x=0
  2. 逐行读入passwd文件,如果发现登录shell是bash结尾则x加1
  3. 全部处理完毕后,输出x的值

awk ‘BEGIN{x=0}/bash$/{x++}END{print x}’ /etc/passwd

练习5:
输出以root开头的行
[root@test ~]# awk -F: ‘/^root/ {print}’ /etc/passwd
root❌0:0:root:/root:/bin/bash

[root@test ~]# awk -F: ‘/^root/’ /etc/passwd #默认为打印
root❌0:0:root:/root:/bin/bash

[root@test ~]# awk -F: ‘$1~/root/’ /etc/passwd #$1代表第一列,~ 代表匹配
root❌0:0:root:/root:/bin/bash

练习6:
找出passwd文件中解释器不是以nologin结尾的行,打印用户名字段,解释器字段
解释:对第7个字段做 !~反向匹配
[root@test ~]# awk -F: ‘$7!~/nologin/{print $1,$7}’ /etc/passwd

练习8:
输出root或adm账户的用户名和解释器字段
[root@test ~]# awk -F: ‘/^(root|adm)/{print $1,$7}’ /etc/passwd
root /bin/bash
adm /sbin/nologin

2.4.数值比较

使用数值/字符串比较设置条件
比较符号:
等于 ==
不等于 !=
大于 >
大于等于 >=
小于 <
小于等于 <=

练习9:
输出第三行的用户名字段,解释器字段
[root@test ~]# awk -F: ‘NR==3{print $1,$7}’ /etc/passwd

练习10:
输出用户UID大于等于1000的用户名、UID、解释器字段
[root@test ~]# awk -F: ‘$3>=1000 {print $1,$3,$7}’ /etc/passwd
nobody 65534 /sbin/nologin
lisi 1000 /bin/bash

练习11:
输出UID小于10的用户名、UID、解释器字段
[root@test ~]# awk -F: ‘$3<10 {print $1,$3,$7}’ /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin

练习12:
输出用户名为 “root”的行
[root@test ~]# awk -F: ‘$1==“root” {print}’ /etc/passwd
root❌0:0:root:/root:/bin/bash

练习13:
输出用户名不是“root”的行
[root@test ~]# awk -F: ‘$1 !=“root”{print}’ /etc/passwd

练习14:
逻辑条件测试
输出账户UID大于10并且小于20的账户信息,打印用户名、UID、解释器
[root@test ~]# awk -F: ‘$3>10 && $3<20 {print $1,$3,$7}’ /etc/passwd
operator 11 /sbin/nologin
games 12 /sbin/nologin

练习15:
输出账户UID大于1000或者小于10的账户信息
[root@test ~]# awk -F: ‘$3>1000 || $3<10’ /etc/passwd

2.5.awk分支结构

if 单分支: if(条件){编辑指令}
if双分支:if(条件){编辑指令1}else{编辑指令2}

if单分支统计passwd文件中UID大于或等于1000的用户个数
[root@test ~]# awk -F: ‘{if($3>=1000) {i++}} END{print i}’ /etc/passwd
24

if双分支统计passwd文件中UID大于等于1000的用户,和小于1000的用户个数
[root@test ~]# awk -F: '{if($3>=1000) {x++}else{i++}} END{print x,i} ’ /etc/passwd
24 43

2.6.awk数组

awk数组的语法格式
数组是一个数组可以存储多个值,具体使用格式如下:
定义数组的格式:数组名[下标]=元素值
调用数组的格式:数组名[下标]
数组的用法:for(变量名 in 数组名){print 数组名[变量]}

[root@test ~]# awk ‘BEGIN{x[0]=10;x[1]=20;print x[0],x[1]}’
10 20

[root@test ~]# awk ‘BEGIN{x[0]++;print x[0]}’
1

2.7.awk循环结构

awk利用for循环遍历数组的用法
— 格式:for(变量名 in 数组名){print 数组名[变量]}
[root@test ~]# awk ‘BEGIN{a[0]=00;a[1]=11;a[2]=22;for(i in a){print i,a[i]}}’
0 0
1 11
2 22

通过awk统计用户登录系统的次数
[root@test ~]# who | awk ‘{ip[$1]++}END{for(i in ip)print i,ip[i]}’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值