文章目录
- 三剑客的文本处理
-
- grep过滤
- awk截取
- sed替换
三剑客的文本处理
grep过滤
用途:在文件中搜索并显示包含指定字符串的行 格式:grep [选项] 模式 目标文件 选项可以不接也可以多接 选项: -i: 搜索时忽略大小写 -v:反转搜索、输出与模式不一致的行 -n:显示符合模式要求的行号 -r:搜索所有文件 -o:只显示匹配的内容 -E:支持更多元字符(支持扩展正则) -A:找到匹配行和后几行 -B:输出匹配行和前几行
图片更直观,下面将显示图片 -i 忽略大小写 -v 匹配不含name(忽略大小写) -n 匹配含hello并显示行号 -r 递归搜索:它可以匹配文件夹下的所有信息like -o 只显示匹配的内容 -E 支持扩张正则 | grep只支持基本正则,不支持扩展正则 | 属于扩展正则,需要连接-E,grep -E = egrep -A1 找到匹配行和后1行 -B1 找到匹配行和前1行
awk截取
用途:文本处理(截取和统计) 格式:awk ‘BEGIN{commands}pattern{commands}END{commands}’ file
注意:BEGIN和END不必要,不能写
位置参数: $0表示整行,$1表示第一列,按此类推 $NF表示最后一列 正则匹配: ~ 模糊匹配 ==精确匹配 ///可以在斜杠中间写正则
有一个buy.txt文本,内容如下,如何?
li 200 liu 500 li 20 li 30 liu 66 xi 99
使用awk数组思想,以$1作为key,$2作为value,分类累加
[root@localhost lianxi]# awk '{name[$1] =$2}END{for (i in name) print i,name[i]}' buy.txt xi 99 li 250 liu 566
-F: 指定输入分割符为 :
[root@localhost lianxi]# cat buy2.txt tt:22 yy:34 xx:90 [root@localhost lianxi]# awk -F: '{print $1}' buy2.txt tt yy xx
OFS=“:” 指定输出分割符为 :
[root@localhost lianxi]# awk 'OFS=":"{print $1,$2}' buy.txt li:200 liu:500 li:20 li:30 liu:66 xi:99
内置变量NR、NF,NR显示行号,$NF最后一列
[root@localhost lianxi]# awk '{print NR,$1,$2,$NF}' buy.txt 1 li 200 200 2 liu 500 500 3 li 20 20 4 li 30 30 5 liu 66 66 6 xi 99 99
复杂用法 如果/etc/passwd的uid大于1000并且shell为bash,输出username,uid,shell,统计合格总数
awk -F: 'BEGIN{num=0} $3>1000 && $NF~/bash/ {print $1,$3,$NF;num } END{print "数量:"num}' /etc/passwd
如果akw命令类似于只有没有动作的模式grep
[root@localhost lianxi]# awk /liu/ buy.txt liu 500 liu 66
gsub 替换
[root@localhost lianxi]# cat name.txt huge shanghai yangmi/beijing [root@localhost lianxi]# awk '{gsub("/"," ",$1);print $1,$2}' name.txt huge shanghai yangmi beijing
如何输出buy.txt第一行和最后一行文件? 第一行很简单NR==1.怎么知道哪一行是最后一行?END,END最后执行,print $输出整行,即输出最后一行
[root@localhost lianxi]# awk 'NR==1{print $0} END{print $0}' buy.txt li 200 xi 99
shell往awk一个传递参数的问题 命令需要由双引号引起,位置参数需要转换
[root@localhost lianxi]# sg=huge [root@localhost lianxi]# useradd huge [root@localhost lianxi]# awk -F: "/$sg/{print \$1}" /etc/passwd huge
if condition statement 多分支:if ; else if ; else 如果$1是liu,输出dage; 如果$1是li,输出xiaodi; 否则,输出meimei
[root@localhost lianxi]# cat buy.txt li 200 liu 500 li 20 li 30 liu 66 xi 99 [root@localhost lianxi]# awk '{if ($1~/liu/) print "dage"; else if ($1~/li/) print "xiaodi"; else print "meimei"}' buy.txt xiaodi dage xiaodi xiaodi dage meimei
substr 切片类似于字符串,但下标从1开始 语法:substr(截取字段、起始位置、长度) 如下第一列,从下标2开始,输出长度为4
[root@localhost lianxi]# cat name.txt huge shanghai yangmi/beijing [root@localhost lianxi]# awk -F"[ /] " '{print substr($1,2,4) }' name.txt uge angm
for循环 循环句用圆括号包括
[root@localhost lianxi]# awk '{name[$1] =$2}END{for (i in name) print i,name[i]}' buy.txt xi 99 li 250 liu 566
system 执行复杂的shell命令 从文本中命令新用户并设置密码username.txt中获取 ; 命令连接符
[root@localhost lianxi]# cat username.txt yuan 123456 he abc123 qian 888888 tan 898989 [root@localhost lianxi]# awk '{system("useradd "$1);system("echo "$2"|passwd "$1" --stdin")}' username.txt 更改用户 yuan 的密码 。 passwd:所有身份验证令牌均已成功更新。 passwd:所有身份验证令牌均已成功更新。 更改用户 he 的密码 。 passwd:所有身份验证令牌均已成功更新。 更改用户 qian 的密码 。 passwd:所有身份验证令牌均已成功更新。 更改用户 tan 的密码 。 passwd:所有身份验证令牌均已成功更新。
使用xargs 内容输出可以一行输出
[root@localhost lianxi]# awk '{print $1}' username.txt|xargs yuan he qian tan
sed替换
核心功能:替换 -i 直接修改原文件 语法:sed -i ‘s/原字符串/目的字符串/’ 输入文件 直接体验,把guangzhou换成shenzhen
[root@localhost lianxi]# cat city.txt beijing shanghai guangzhou [root@localhost liaxi]# sed -i 's/guangzhou/shenzhen/' city.txt
[root@localhost lianxi]# cat city.txt
beijing
shanghai
shenzhen
c 指定替换某行 2c 目标内容 :表示替换原第二行内容为目标内容
[root@localhost lianxi]# sed -i '2c hangzhou' city.txt
[root@localhost lianxi]# cat city.txt
beijing
hangzhou
shenzhen
p 打印,和 -n 搭配使用,不然达不到效果
[root@localhost lianxi]# sed '2,3p' city.txt
beijing
hangzhou
hangzhou
shenzhen
shenzhen
[root@localhost lianxi]# sed -n '2,3p' city.txt
hangzhou
shenzhen
! 取反:不显示2到3行即显示第1行,4到n行
[root@localhost lianxi]# sed -n '2,3!p' city.txt
beijing
~ 步长:从1开始,每次增加2 1~2p 即表示输出奇数行
[root@localhost lianxi]# sed -n '1~2p' city.txt
beijing
shenzhen
-r 如果用到扩展正则需要接 -r 例子:不显示注释行或空行
[root@localhost lianxi]# sed -nr '/^#|^$/!p' /etc/ssh/sshd_config
[root@localhost lianxi]# sed -n -r '/^#|^$/!p' /etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile .ssh/authorized_keys
d 删除 例子:删除无效行
[root@localhost lianxi]# sed -r '/^#|^$/d' sshd_config |cat
-i 插入:在前面插入 -a 追加:在后面追加
[root@localhost lianxi]# cat city.txt
beijing
hangzhou
shenzhen
[root@localhost lianxi]# sed -i '3i wuhan' city.txt
[root@localhost lianxi]# sed -i '3a nanjing' city.txt
[root@localhost lianxi]# cat city.txt
beijing
hangzhou
wuhan
nanjing
shenzhen