韩国男女直接做的视频网站,三种网络营销方式,wordpress文章导出,中小企业网站建设咨询Linux-文本三剑客前言一、grep二、sed三、awk模式 -- 正则表达式关系表达式、运算符表达模式匹配表达式动作 输出流程控制参数传递#xff0c;awk接受外部变量统计数组的使用分组统计练习常用内置函数前言
grep、sed、awk 被称为 “文本三剑客”#xff0c;它们是处理文本文…
Linux-文本三剑客前言一、grep二、sed三、awk模式 -- 正则表达式关系表达式、运算符表达模式匹配表达式动作 输出流程控制参数传递awk接受外部变量统计数组的使用分组统计练习常用内置函数前言
grep、sed、awk 被称为 “文本三剑客”它们是处理文本文件的强大工具广泛用于日志分析、数据提取、文本转换等场景。三者各有侧重常结合管道|使用
基于行处理的文本命令
grep 过滤文本sed 过滤替换文本awk 截取文本统计文本 输出/etc/passwd文件里的uid大于1000的用户的信息输入格式如下 username: cali uid: 1001 gid: 1001 awk -F: ‘$31000{print “username:”$1,“uid:”$3,“gid:”$4}’ /etc/passwd
while 和 read
IFS 输入字段分割符 input field separator [roothz shell]# cat uid_gid.sh #!/bin/bash
while IFS“:” read username x uid gid others do if (( uid1000));thenechousername:uid 1000 ));then echo username:uid1000));thenechousername:username uid: $uid gid: $gid fi done /etc/passwd
[roothz shell]# cat uid_gid_2.sh #!/bin/bash
cat /etc/passwd|awk -F: ‘{print $1,$3,$4}’|while read username uid gid do if (( uid1000));thenechousername:uid 1000 ));then echo username:uid1000));thenechousername:username uid: $uid gid: $gid fi done
截取出根分区的使用率 grep ^ 表示以什么开头 $ 表示以什么结尾
[roothz shell]# df |grep “/KaTeX parse error: Expected EOF, got # at position 72: …[roothz shell]#̲ df |grep /”|awk {print KaTeX parse error: Expected EOF, got } at position 2: 5}̲ 33% [roothz …|awk ‘{print $5}’|tr -d “%”
一、grep
grep 过滤 通用的正则表达式分析程序 grep、egrep、fgrep 做匹配来过滤的
正则表达式 文本过滤 输入校验
pattern 模式 --》模板 可以接受一个正则表达式
用途在文件中查找并显示包含指定字符串的行 格式grep [选项]… 模式 目标文件
-i查找时忽略大小写-v反转查找输出与模式不相符的行-n显示符合模式要求的行号-r递归搜索所有文件-o只显示匹配的内容-E 支持更多的元字符支持扩展正则-A: 找到匹配行以及后几行-B输出匹配行以及前几行
过滤掉不以#号开头和行过滤掉空行
[rootdb ~]# egrep -v ^#|^$ sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
DenyUsers sc
SyslogFacility AUTHPRIV
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem sftp /usr/libexec/openssh/sftp-server统计不同状态码出现次数
[rootdb ~]#egrep -o HTTP/1.1\ [1-5][0-9]{2} access.log-20250828 |sort|uniq -c21 HTTP/1.1 20038 HTTP/1.1 3044 HTTP/1.1 4042 HTTP/1.1 500过滤出文档中的ip地址ip正则表达式 ipv4 [0-255].[0-255].[0-255].[0-255] egrep ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) 过滤出/var/log/message中含有error的行以及error信息的后5行 grep -i -A 5 error /var/log/messages 二、sed
sed – 编辑文本过滤文本 非交互式 方便在脚本中使用
sed命令格式 直接处理文本 sed [选项] command file
前一个命令的输出也可以作为sed的输入 cat file| sed [选项] command
选项
-i 直接修改文件内容-n 只打印模式匹配的行-f 将sed的命令写入一个文件内从脚本文件中读取内容并执行-r 支持正则表达式-e 执行多个编辑命令时
sed常用指令 [address]command
p – print 打印输出模块行 取反 表示后面的命令对选定的行没有作用n next 读取下一个输入的行用下一个命令处理新的行i\ insert 在当前行的上面插入文本a\ append 在当前行的后面插入文本d delete 删除行r r filename 从filename读取 将filename的内容放在匹配的行之后w w filename 将匹配到的内容写入文本N 追加下一行到当前模块的后面s 替换操作
多条命令进行组合
使用 分号 使用-e还可以使用 |
address – 确定的范围 1、空地址 – 全文处理 2、单地址 – 7p 3、步进地址 1~2 2~2 4、地址对
N,M 从第N行到第M行N,M 从第n行开始向下匹配M行N,/pattern/ 从第n行到 pattern匹配的行 pattern支持正则表达式 使用//包裹起来/pattern1/,/pattern2/ 从pattern1匹配到 pattern2 匹配的行/pattern/ 匹配pattern的行$ 最后一行
打印文件所有行并输出行号 [rootdb ~]# sed -n “p” test.txt 1 aaa abc 2 xxx yyy 3 ppp 4 nihao 5 hello 6 sctl world 7 balabala 8 xixi 9 haha 仅打印第7行 [rootdb ~]# sed -n “7p” test.txt 7 balabala 打印所有奇数行 [rootdb ~]# sed -n “1~2p” test.txt 1 aaa abc 3 ppp 5 hello 7 balabala 9 haha [rootdb ~]# sed -n “p;n” test.txt 1 aaa abc 3 ppp 5 hello 7 balabala 9 haha 打印所有偶数行 [rootdb ~]# sed -n “2~2p” test.txt 2 xxx yyy 4 nihao 6 sctl world 8 xixi [rootdb ~]# sed -n “n;p” test.txt 2 xxx yyy 4 nihao 6 sctl world 8 xixi 打印1到3行 [rootdb ~]# sed -n “1,3p” test.txt 1 aaa abc 2 xxx yyy 3 ppp 第 1 行开始打印当前行 后续 3 行 [rootdb ~]# sed -n “1,3p” test.txt 1 aaa abc 2 xxx yyy 3 ppp 4 nihao 从第 1 行开始打印到 “首次包含字符 s 的行” [rootdb ~]# sed -n “1,/s/p” test.txt 1 aaa abc 2 xxx yyy 3 ppp 4 nihao 5 hello 6 sctl world 打印所有包含字符串 sctl 的行 [rootdb ~]# sed -n “/sctl/p” test.txt 6 sctl world 在第 7 行之后插入一行内容 this is test [rootdb ~]# sed “7 a\this is test” test.txt 1 aaa abc 2 xxx yyy 3 ppp 4 nihao 5 hello 6 sctl world 7 balabala this is test 8 xixi 9 haha 在第 7 行之前插入一行内容 this is test [rootdb ~]# sed “7 i\this is test” test.txt 1 aaa abc 2 xxx yyy 3 ppp 4 nihao 5 hello 6 sctl world this is test 7 balabala 8 xixi 9 haha 删除第七行 [rootdb ~]# sed “7d” test.txt 1 aaa abc 2 xxx yyy 3 ppp 4 nihao 5 hello 6 sctl world 8 xixi 9 haha sed替换 [address]s/pattern/replacement/flags - 不修改原文件
支持正则表达式支持分组向后引用 表示已匹配的字符串flags: 替换标记g 表示行内全面替换p 表示打印行n n表示数字 1~512 表示替换第几个ng 从第几个开始替换
在第 1-5 行中将所有字母 a小写替换为 *
[rootdb ~]# sed 1,5s/a/\*/g test.txt
1 *** *bc
2 xxx yyy
3 ppp
4 nih*o
5 hello
6 sctl world
7 balabala
8 xixi
9 haha 在第 1-5 行中将所有 a、b、c、d小写连续字母范围替换为 *
[rootdb ~]# sed 1,5s/[a-d]/\*/g test.txt
1 *** ***
2 xxx yyy
3 ppp
4 nih*o
5 hello
6 sctl world
7 balabala
8 xixi
9 haha 直接修改要用 -i 选项 sed -i s/old/new/g test.txt
使用 -i 前建议先执行不加 -i 的命令预览效果确认替换正确 三、awk
awk是一种编程语言对文本、数据进行处理 过滤、统计、截取 内部编程和c语言有相同之处
语法形式 awk [选项] awk命令脚本 file awk [选项] -f scriptfile file
常用的命令选项
-F 指定分隔符 默认空白符-v varvalue 将外部变量传递给awk-f scripfile 从脚本文件中读取awk命令
awk命令脚本基本结构体由三大块组成 BEGIN{语句块} /模式/{动作} END{ 语句块}
BEGIN、模式通用语句块、END 都是可选部分
第一部分执行BEGIN语句块中的内容在处理文本之前读取行之前被执行。一般用在初始化变量打印一些表头第二部分pattern语句块 通用语句块读取文本的每一行交给这个语句块处理第三部分读取完所有的行之后执行 统计、分析结果这些信息在END中完成
以a1.txt为例
[rootdocker ~]# cat a1.txt
1 a1 b1 3
2 a2 b1 4
3 a3 b2 2
4 a1 b2 5
5 a2 b3 4
6 a3 b3 3
[rootdocker ~]# awk BEGIN{print start....;print start2.....}{print $2}END{print end......} a1.txt
start....
start2.....
a1
a2
a3
a1
a2
a3
end......
[rootdocker ~]# awk BEGIN{print start....;print start2.....}{print $2} a1.txt
start....
start2.....
a1
a2
a3
a1
a2
a3
[rootdocker ~]# awk {print $2} a1.txt
a1
a2
a3
a1
a2
a3
[rootdocker ~]# awk BEGIN{print start....;print start2.....} a1.txt
start....
start2.....
[rootdocker ~]# awk BEGIN{print 3/2} a1.txt
1.5
[rootdocker ~]# awk {print 3/2} a1.txt
1.5
1.5
1.5
1.5
1.5
1.5
[rootdocker ~]# echo|awk {print 3/2}
1.5
[rootdocker ~]# echo|awk {print 32}
[rootdocker ~]# echo|awk {print 32}
0问题根据 awk 的逻辑判断规则数值比较结果会以 0假或 1真 输出比较结果为假输出了0但是比较结果为真并没有输出1
通用语句块 – 模式和动作 模式 – 过滤 /正则表达式/ 可以使用正则表达式匹配 关系表达式 || 、运算符表达式 模式匹配表达式 用运算符 ~ !~ 表示匹配或不匹配 动作 动作是由一个或多个命令、表达式组成命令之间用分号隔开 变量或数组的赋值输出使用内置函数控制流语句
模式 – 正则表达式
[rootdocker ~]# awk -F: /ss/{print} /etc/passwd
dbus:x:81:81:System message bus:/:/sbin/nologin
sssd:x:998:998:User for sssd:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/:/usr/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/usr/sbin/nologin[rootdocker ~]# awk -F: /^ss/{print} /etc/passwd
sssd:x:998:998:User for sssd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/usr/sbin/nologin关系表达式、运算符表达
[rootdocker ~]# awk -F: $32000{print $1} /etc/passwd
[rootdocker ~]# awk -F: $32001{print $1} /etc/passwd
[rootdocker ~]# awk -F: $31010 $3 2000{print $1} /etc/passwd
[rootdocker ~]# awk -F: $31010 $3 2000{print} /etc/passwd算术运算符 - * / % –
其他运算符: 类似于javascript的三元运算in
[rootdocker ~]# echo |awk BEGIN{abbb;print abbb?ok:error}
ok模式匹配表达式
[rootdocker ~]# awk -F: $1 ~ /ss{print} /etc/passwd
[rootdocker ~]# awk -F: $1 ~ /^ss/{print} /etc/passwd
# 找到家目录不在/home 目录下的所有用户信息
[rootdocker ~]# awk -F: $6 !~ /^\/home\//{print} passwd
# 找到登录shell为/bin/bash并且uid大于500的用户信息
[rootdocker ~]# awk -F : $7/bin/bash $3500 {print $0} /etc/passwd动作 输出
内部变量
$0 表示整行文本$1 表示分隔出来的第一列文本$n 表示分隔出来的第n列文本NF 每行$0的字段数 最后一列可表示为$NFNR 当前处理的行号FS 当前的输入分隔符默认是空白字符空格和tabfield separatorOFS 当前的输出分隔符默认是空格字符空格output field separator
[rootdocker ~]# awk {print 最后一列为:$NF} a1.txt
最后一列为:end
最后一列为:4
最后一列为:2
最后一列为:end
最后一列为:4
最后一列为:3
[rootdocker ~]# awk {print 最后一列为:$NF $(NF-1)} a1.txt
最后一列为:end 3
最后一列为:4 b1
最后一列为:2 b2
最后一列为:end 5
最后一列为:4 b3
最后一列为:3 b3
[rootdocker ~]# awk NR3{print 最后一列为:$NF $(NF-1)} a1.txt
最后一列为:end 5
最后一列为:4 b3
最后一列为:3 b3
[rootdocker ~]# awk BEGIN{FS ;OFS**}{print $1,$2} a1.txt
1**a1
2**a2
3**a3
4**a1
5**a2
6**a3
[rootdocker ~]# awk BEGIN{FS }{print $1,$2} a1.txt
1 a1
2 a2
3 a3
4 a1
5 a2
6 a3流程控制
[rootdocker ~]# echo |awk BEGIN{num100;if(num90) {print 大于90} else {}}
大于90
[rootdocker ~]# echo |awk BEGIN{num100;if(num90){print 大于90}else{print 小于等于90}}
大于90参数传递awk接受外部变量
1、使用双引号 2、使用 -v 选项 3、将变量的接受放后面
[rootdocker ~]# a100
[rootdocker ~]# b200
# 1.双引号
[rootdocker ~]# echo|awk {print $a$b}
300
[rootdocker ~]# echo|awk {print $a$b}
0
# 2.-v
# 注意没有空格
[rootdocker ~]# echo|awk -v var1$a var2$b {print var1var2}
awk: fatal: cannot open file {print var1var2} for reading: No such file or directory
[rootdocker ~]# echo|awk -v var1$a var2$b{print var1var2}
300
# 3.变量放后面
# 注意空格
[rootdocker ~]# echo|awk {print var1var2}var1$a var2$b
200
[rootdocker ~]# echo|awk {print var1var2} var1$a var2$b
300统计
求取a1.txt文件中第四列的平均值、最大值、最小值
[rootdocker ~]# awk NR1{max$4} {max($4max)?$4:max} END{print max} a1.txt
5
[rootdocker ~]# awk NR1{min$4} {min($4min)?$4:min} END{print min} a1.txt
2
[rootdocker ~]# awk BEGIN{sum0;count0}{sum$4;count1}END{print sum/count} a1.txt
3.5数组的使用
分析、统计 分类聚合
类似python中的字典 arr[1]“aa” arr[2]“bb” arr[‘a’] 1 #k-v存储 key-value arr[‘b’] 2 读取数组 { for (i in arr){print arr[i]}} { for (i1;ilen;i) {print arr[i]}} # 没有相应的索引也可以取值为空
[rootdocker ~]# echo |awk BEGIN{t1[a]1;t2[b]2}{if(t1[a]1){print ok}}
ok
[rootdocker ~]# echo |awk BEGIN{t1[a]1;t2[b]2}{if(t1[a]1){print t1[c]}}[rootdocker ~]# echo |awk BEGIN{info[name]sc; info[age]7}{print info[name]}
sc
[rootdocker ~]# echo |awk BEGIN{info[name]sc; info[age]18}{print info[age]}
18
[rootdocker ~]# echo |awk BEGIN{info[name]sc; info[age]7}{print info[sex]}# 判断属组中有没有这个key -- in
[rootdocker ~]# echo | awk BEGIN{info[name]sc;info[age]18}{if(name in info){print yes}}
yes分组统计
[rootdocker ~]# cat stu.txt
工号 姓名 性别 部门 工资
1 张三 女 SA 8000
2 李四 男 PE 7000
3 王二 女 SA 9000
4 小李 男 PE 8000
5 小张 女 PE 9000
6 小谢 男 SA 9000
7 小米 男 SA 8000
5 小陈 女 PE 7000
[rootdocker ~]# awk NR1{ stuff[$3]$4 } END{ for(i in stuff) {print i--stuff[i] }} stu.txt
男--0
女--0
[rootdocker ~]# awk NR1{ stuff[$3]$5 } END{ for(i in stuff) {print i--stuff[i] }} stu.txt
男--32000
女--33000# 统计每个部门每个性别 各发出去多少工资 -- 按什么分组就以什么作为key
[rootdocker ~]# awk NR1{ stuff[$3--$4]$5 } END{ for(i in stuff) {print i--stuff[i] }} stu.txt
女--SA--17000
女--PE--16000
男--SA--17000
男--PE--15000练习
# 统计本机各个连接状态的数量
netstat -anplt|awk NR2{ state[$6]} END{ for(i in state) {print i--state[i] }}
LISTEN--27
ESTABLISHED--70# 降序统计客户端 IP 的访问次数
cat access.log | awk {print $1}|sort|uniq -c|sort -rn# 降序统计 Referer 中含 IP 地址的访问次数
cat access.log | awk {print $11}|sort|uniq -c|egrep ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|sort -rn# 统计nginx访问日志的每分钟每个路径访问次数
awk -F[ :] {count[$4$5--$10]}END{for(i in count){print i:count[i]}} access.log常用内置函数
算术相关 int(x)
rand() 0n1sqrt() 开平方
字符串相关
length(string) 长度split(string, A,[指定的分隔符]) 切割字符串substr(string, M, [N]) 对string进行截取从M的位置开始截取N个
统计access.log日志中每个小时每个路径访问次数
awk {count[substr($4,2,14)--$7]}END{for(i in count){print i:count[i]}} scwebsite2_ssl.log