第六篇:文本四剑客 awk、sed、grep、find

四剑客--grep⭐⭐⭐⭐⭐

过滤:在文件或管道中进行查找,找出想要的内容,默认按照行显示

grep '你想查找的内容' 被查询的文件

  grep选项

grep选项  说明 
-n  line-number  显示行号
-v   排除、取反(将不含有的显示出来)
-i   ignore-case  过滤的时候忽略大小写
-o only  只输出匹配到的内容,而不是整行
-w 精确匹配
-P perl正则

  案例与应用 

 1)基本用法

# 案例:在/etc/passwd中过滤出包含root的行
[root@yuan ~]# grep 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# 案例:在/var/log/secure中过滤出包含Failed password的行并统计
[root@yuan ~]# grep 'session' /var/log/secure | wc -l
5

 2)显示内容和行号

# 案例:显示/etc/passwd中宝航root的行及行号
[root@yuan ~]# grep -n 'root' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

 3)过滤的时候不区分大小写

# 案例:过滤出/var/log/secure中的failed password 的行且不区分大小写
[root@yuan ~]# grep -i 'failed password' /var/log/secure
Sep  9 19:54:21 yuan sshd[17674]: Failed password for root from 10.0.0.200 port 51568 ssh2
Sep  9 19:54:26 yuan sshd[17674]: Failed password for root from 10.0.0.200 port 51568 ssh2
Sep  9 19:54:29 yuan sshd[17674]: Failed password for root from 10.0.0.200 port 51568 ssh2

 4)排除

复制代码
# 当查找的时候,不知道具体需要什么,但是你知道你什么不想要
    grep命令的排除选项,过滤出不包含xxx内容的行

# 案例:排除/etc/passwd中的nologin的行
[root@yuan ~]# grep -v 'nologin' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
复制代码

四剑客--find⭐⭐⭐⭐⭐

查找:在指定目录中查找文件

find  目录  指定类型  指定名字

  find选项

find命令选项 说明
-type 什么类型的文件(f表示文件,d表示目录)
-name 文件名
-size 根据大小查找文件(+表示大于、-表示小于)
-mtime 根据修改时间查找文件
-maxdepth 指定最多找多少层目录

  基础案例 

 1)精确查找与模糊查找

复制代码
# 案例:在/etc/目录中找出文件名叫hostname文件
精确查找(指定文件名)
[root@yuan ~]# find /etc/ -type f -name 'hostname'
/etc/hostname

# 案例:找出/etc/目录下面以.conf结尾的文件
模糊查找
[root@yuan ~]# find /etc/ -type f -name '*.conf'
/etc/resolv.conf
/etc/pki/ca-trust/ca-legacy.conf
/etc/yum/pluginconf.d/fastestmirror.conf
/etc/yum/pluginconf.d/langpacks.conf
复制代码

 2)根据大小查找

  • -size选项,根据大小查找文件
    • 大于  使用+加号  -size +10k  大于10k的文件
    • 小于  使用-减号  -size -10k 小于10k的文件
# 案例:在/etc/目录下面找到大于1Mb的文件
[root@yuan ~]# find /etc/ -type f -size +1M
/etc/selinux/targeted/active/policy.kern
/etc/selinux/targeted/contexts/files/file_contexts.bin
/etc/selinux/targeted/policy/policy.31
/etc/udev/hwdb.bin

 3)根据修改时间查找

# -mtime选项
    +7  找出7天前的文件
    -7   找出7天内的文件
# 案例:找出/etc/目录下以.conf结尾,7天之前的文件
[root@yuan ~]# find /etc/ -type f -name '*.conf' -mtime +7
/etc/pki/ca-trust/ca-legacy.conf
/etc/yum/pluginconf.d/fastestmirror.conf
/etc/yum/pluginconf.d/langpacks.conf

 4)进阶选项

复制代码
# 案例:查找文件时指定最多找多少层目录
[root@yuan ~]# find / -maxdepth 2 -type f -name '*.conf'
/etc/resolv.conf
/etc/asound.conf
/etc/libuser.conf
-maxdepth 2  :指定find命令查找的最大层数,不加上就是所有层

# 案例:查找的时候不区分文件名的大小写
find /   -type f -iname "*.conf"
# ignore case
复制代码

  find命令与其他命令配合(难点)⭐⭐⭐⭐⭐

find不要与交互式命令配合:find+vi/vim

  • find+简单命令:find找出想要的文件删除、查看详细信息、显示文件内容、过滤
  • find+打包压缩:find找出文件进行打包压缩
  • find+cp/mv:find找出文件后复制或移动
环境准备:
mkdir -p /yuan/find/
touch /yuan/find/jiang{01..10}.txt

 1)find+简单命令

案例:找出/yuan/find/以.txt结尾的文件并显示详细信息

方法一:find+反引号+其他命令
ls -l `find /yuan/find/ -type f -name '*.txt'`
方法二:find |xargs
复制代码
# 我们发现find命令使用管道把数据传输给其他命令失败
    find /yuan/find/ -type f -name '*.txt' | ls -l    # 查找结果不正确

故障原因:
    ls 选项 参数
    前面的命令通过管道传递给后面的命令传递的是字符串
    管道向ls命令中传递的是字符串
解决方法:
    通过|xargs 把前面的命令传递过来的字符串转换为后面命令可以识别的参数

find /yuan/find/ -type f -name '*.txt' |xargs ls -l 
复制代码
方法三:find+ -exec(了解)
复制代码
find /oldboy/find/  -type f  -name '*.txt'   -exec ls -l  {} \;
-exec是find选项,表示find找出文件后要执行的命令
{} 表示前面find命令找出的文件.
\;表示命令结束,固定格式.

温馨提示:
    {}与\中间有空格
    \与;中间没有空格
    # 否者:find: 遗漏“-exec”的参数
复制代码

 2)find+打包压缩

案例:找出/yuan/find/以.txt结尾的文件放在/tmp/find.tar.gz 

方法一:find+反引号+其他命令
tar zcf /tmp/find.tar.gz `find /yuan/find/ -type f -name '*.txt'`
方法二:find |xargs
find /yuan/find/ -type f -name '*.txt' |xargs tar zcf /tmp/find-xargs.tar.gz 
方法三:find+ -exec(了解)
find /yuan/find/ -type f -name '*.txt' -exec tar zcf /tmp/find-exec.tar.gz {} \;

 3)find+cp/mv

案例:找出/yuan/find/以.txt结尾的文件然后复制到/tmp/目录下

方法一:find+反引号+其他命令

cp `find /yuan/find/ -type f -name '*.txt'` /tmp/

方法二:find + |xargs

find /yuan/find/ -type f -name '*.txt' |xargs cp -t /tmp/

方法三:find + -exec
find /yuan/find/  -type f  -name '*.txt' -exec cp {} /tmp/ \; 

四剑客--sed⭐⭐⭐⭐⭐

 

  • 核心功能:取行、过滤、替换修改文件内容
  • 难点:后向引用(截取)
  • sed stream editor 流编辑器

  sed命令格式与选项

命令 选项 详细格式 参数
sed 选项 条件指令(找谁干啥) 文件
选项 说明
-n 取消默认输出(sed处理文件时会默认输出每一行内容)
-r sed支持扩展正则
-i 修改文件内容(该选项放在最后)
-i.bak 先进行备份,然后修改文件内容(该选项放在最后)

  sed命令执行过程

  sed增删改查--查找(p)⭐⭐⭐⭐⭐

  • 一种类似于grep的模糊查找
  • 一种是可以指定行号的精确查找

 1)案例01:取出/etc/passwd文件的第三行

sed -n '3p' /etc/passwd

 2)案例02:取出/etc/passwd文件的第2行到第5行

sed -n '2,5p' /etc/passwd

 3)案例03:过滤出/etc/passwd文件中以root开头的行

sed -n '/^root/p' /etc/passwd
sed进行过滤的时候需要使用//,并且//里面支持正则
如果需要使用扩展正则,则使用sed -r 选项

 4)案例04:获取范围内的日志

复制代码
[root@yuan ~]# cat /yuan/sed.txt 
101,yuan,CEO
102,xiaojiang,CTO
103,猿小姜666,COO
104,xiaozhang,CFO
105,xiaoxu,CIO
110,xiaowang,COCO

[root@yuan ~]# clear
[root@yuan ~]# sed -n '/102/,/104/p' /yuan/sed.txt
102,xiaojiang,CTO
103,猿小姜666,COO
104,xiaozhang,CFO
复制代码

 5)案例05:只显示第3行和第5行

  sed增删改查--修改(替换)(s###g)⭐⭐⭐⭐⭐

  • 基础使用

 1)案例01:将/yuan/sed.txt文件中yuan替换成xiaojiang

复制代码
# sed替换格式说明
    sed -i 's#找谁#替换成什么#g' /yuan/sed.txt
    推荐使用:###、@@@、///
    s: substitute 替换
    g: global 全局替换(将这一行所有的内容都进行替换,否则只替换每一行第一个匹配的内容)

# 使用时注意
    使用sed进行替换时,先用sed 's#找谁#替换成什么#g' /yuan/sed.txt 如果确定无误后再使用-i

# 修改文件内容之前进行备份,然后修改文件内容
    sed -i.bak 's#yuan#xiaojiang#g' /yuan/sed.txt
一般用于替换某一个文件,如果替换多个文件则打包压缩备份
复制代码

  • 后向引用(反向引用)
复制代码
# 应用说明:
    适用于sed命令处理/提取一行中的某些部分
    sed命令配合正则实现取列(类似于awk取列)
# 使用格式:
    使用替换的格式  s###g
    前面两个井号之间通过正则与()对数据进行分组
    后面两个井号之间通过\数字 调用前面分组的内容
    整体就是后面调用前面分组的内容,称之为反向引用/后向引用
    应用场景:某一行中对数据进行架构与处理,提取某一部分数据
复制代码

 案例01:调换/etc/passwd第一列和最后一列的内容

cp /etc/passwd /yuan/

[root@yuan ~]# sed -r 's#^(.*)(:/.*:)(.*)$#\3\2\1#g' /yuan/passwd
/bin/bash:/root:root:x:0:0:root
/sbin/nologin:/bin:bin:x:1:1:bin

 案例02:取出网卡ip地址

ip address show eth0 (ip a s eth0)取出指定网卡的信息

# 方法一:
    ip address show eth0 |sed -n '3p' |sed -r 's#^(.*et )([0-9.]+)(.*)#\2#g'

# 方法二:
    ip address show eth0 |sed -rn '3 s#^(.*et )([0-9.]+)(.*)#\2#g  p'

 案例03:取出stat /etc/hosts中的0644或644

[root@yuan ~]# stat /etc/hosts |sed -n '4p' |sed -r 's#(.*:\()([0-9]+)(.*)#\2#g'
0644
[root@yuan ~]# stat /etc/hosts |sed -n '4p' |sed -r 's#(.*:\(0)([0-9]+)(.*)#\2#g'
644

  sed增删改查--删除(d)⭐⭐⭐⭐⭐

  • d(delete)  sed命令删除功能按照为单位进行
  • 如果仅仅删除某一行中某一些字符推荐使用's#[a-z]##g'
# 删除/yuan/sed.txt中的第三行
    [root@yuan ~]# sed -i '3d' /yuan/sed.txt  # 由于sed -i 是就地编辑,不会输出# 排除/删除文件中的空行和带注释的行
    egrep  -v '^$|#' /etc/ssh/sshd_config
    sed -r '/^$|#/d' /etc/ssh/sshd_config

 sed增删改查--增加(c a i)⭐⭐

c a i  
a  append 在指定行后面追加内容
i  insert 在指定行上面个插入一行
c  replace 替换指定行的内容
复制代码
[root@yuan ~]# sed '3a 999,xiaojun,UFO' /yuan/sed.txt
101,yuan,CEO
102,xiaojiang,CTO
103,猿小姜666,COO
999,xiaojun,UFO
104,xiaozhang,CFO
105,xiaoxu,CIO
110,xiaowang,COCO

[root@yuan ~]# sed '3i 666,xiaojun,UFO' /yuan/sed.txt
101,yuan,CEO
102,xiaojiang,CTO
666,xiaojun,UFO
103,猿小姜666,COO
104,xiaozhang,CFO
105,xiaoxu,CIO
110,xiaowang,COCO

[root@yuan ~]# sed '3c 111,xiaohang,TOF' /yuan/sed.txt
101,yuan,CEO
102,xiaojiang,CTO
111,xiaohang,TOF
104,xiaozhang,CFO
105,xiaoxu,CIO
110,xiaowang,COCO
复制代码

四剑客--awk⭐⭐⭐⭐⭐

  概述

 格式⭐⭐⭐⭐⭐

复制代码
awk [options] 'pattern {action}' filename

# options
    -F:指定字段分隔符
    -v:定义变量
# pattern(条件:可以是简单的字符串、正则表达式、条件表达式)
    /pattern/:匹配包含pattern的行
    NR==1:匹配第一行
# action(动作):
    print:输出文本
    gsub:全局替换指定字符串
复制代码

 

 执行流程⭐⭐⭐⭐⭐

  取行⭐⭐⭐⭐⭐

awk + NR 取出指定的行、指定范围的行
awk + // 过滤

 

 案例01:取出/etc/passwd的第一行内容

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

# NR:指行号
# {print $0}:输出整行内容(awk满足条件后默认的动作)

 

 案例02:取出/etc/passwd第二行到第五行内容

awk 'NR>=2 && NR<=5' /etc/passwd
awl 'NR==2,NR==5' /etc/passwd

 

 

 案例03:过滤出/etc/passwd文件中包含root或nobody的行

awk '/root|nobody/' /etc/passwd

 

 案例04:过滤出/etc/passwd文件中从包含root的行到包含nobody的行的内容

awk '/root/,/nobody/' /etc/passwd

  取列⭐⭐⭐⭐⭐

$ $0、$NF
-F':'   指定分隔符 awk取列的时候默认是通过空白字符(空格、连续空格)进行分割

 

 案例01:使用awk取出ls -lh /etc/hosts 的大小列和最后一列

 

ls -lh /etc/hosts |awk '{print $5,$NF}'

# $数字,表示取列($0表示取这一行)
# $NF:表示最后一列(NF:每行有多少列)
# $(NF-1) :表示倒数第二列
# awk输出对齐:column -t

 

 案例02:取出/etc/passwd中第1列,第3列,最后一列内容

awk -F ':' '{print $1,$3,$NF}' /etc/passwd |column -t

 

 案例03:指定复杂分隔符取出ip

ip address show eth0 |awk 'NR==3 {print $2}' |awk -F'/' '{print $1}'
ip address show eth0 |awk -F '[ /]' 'NR==3{print $6}'
ip address show eth0 |awk -F '[ /]+' 'NR==3 {print $3}'

 

  取行与取列⭐⭐⭐⭐⭐

 案例01:取出/etc/passwd文件中第3列大于100的行的第1列、第3列、最后1列

awk -F ':' '$3>=100 {print $1,$3,$NF}' /etc/passwd |column -t

 

 案例02:如果系统swap使用超过0则输出"异常系统开始占用swap"

free |awk '/Swap/ && $3>0 {print "异常系统开始占用swap"}'
free |awk 'NR==3 && $3>0 {print "异常系统开始占用swap"}'

 

 案例03:过滤出/etc/passwd第4列的数字以0或1开头的行的第1列、第3列、第4列

awk -F ':' '$4~/^[01]/ {print $1,$3,$4}' /etc/passwd |column -t

~ :表示包含的意思 $1 ~ /root/ 表示第1列中包含root
!~ :表示不包含

 

  awk统计与计算⭐⭐⭐⭐⭐

  • 类似于 wc -l 统计次数
  • 进行求和,累加

 统计次数

 

wc -l /etc/passwd
awk '{i++} END{print i}' /etc/passwd

# END{}内容会在awk读取文件完成时执行
# END{}一般用于输出执行结果

 

 计算总和

seq 10 |awk '{i=i+$1} END{print i}'

四剑客总结⭐⭐⭐⭐⭐

  是否支持正则表达式

四剑客 基础正则 扩展正则
find find -regex 不支持
grep 支持 grep -E(egrep)
sed 支持 sed -r(sed -E)
awk 支持 支持

  四剑客对应的功能

四剑客 功能
find 查找文件
grep/egrep 过滤
sed 过滤、取行、替换、删除
awk 过滤、取行、取列、统计计算、判断、循环
posted @   猿小姜  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示