day19-20-四剑客-find-grep-sed-awk

发布于:2025-05-22 ⋅ 阅读:(19) ⋅ 点赞:(0)

1. 通配符(匹配文件名)

" ? " 表示一个非空的任意字符
\ 表示转义字符,能让特殊字符失去原有的功能
[] 表示匹配" [] "包含的其中的一个字符
[a-z] 表示匹配所有的小写字母
[A-Z] 表示匹配所有大写的字母
[a-Z] 表示匹配所有字母
[1-9] 表示匹配所有的数字
[^] 表示匹配不是中括号内的一个字符
* 表示匹配任意数量的字符

grep(抓)正常只能抓取文件的内容,配合管道,可以抓取任何内容,在管道引用场景,使用频率非常高

2. 正则表达式(匹配文件内容)grep

^			表示以....开头
$			表示以....结尾
.			表示匹配任意一个字符
.*		表示匹配0个或若干个字符
h*		表示匹配0个或若干个h

[abc]	表示匹配a或b或c
[a-z]	表示匹配所有小写字符
[A-Z]	表示匹配所有大写字符
[a-Z]	表示匹配所有字符
[0-9]	表示匹配所有数字
[^] 	表示匹配不是中括号内的一个字符

# []中的特殊符号会还原本意,除了^

grep 是用来过滤“行”
grep -o 只显示抓取的内容
grep -n	显示行号
grep -r 递归过滤
grep -v 反向抓取内容

grep -i 忽略大小写
grep -c 统计字符出现的次数,一行算一个
grep -w --word-regexp  # 只显示全字符,符合的列,精确匹配
grep -E 和 egrep(支持扩展的grep)是一样的,但是有一些基础的linux系统,不带egrep命令
grep -A	after,过滤后把后面的n行内容同时显示出来
grep -B	before,过滤后把前面的n行内容同时显示出来
grep -C 过滤后把上下的n行内容同时显示出来

3. 扩展正则(匹配文件内容)egrep

?			表示匹配0个或1个字符
a?		表示匹配0个或1个a
a+		表示匹配1个或若干个a
a|b		表示匹配a或者b

a{2}	表示匹配最少2次a
a{2,5}表示匹配最少出现2次a,最多出现5次a
a{,5} 表示匹配最多出现5次a

()  表示整体
\b  表示边界
\<   \> 表示边界

# 取出lscpu中的cache内容
lscpu |egrep 'L(1d|1i|2|3) cache'

# 取身份证号码
cat ip.txt | egrep '\b[0-9]{17}[0-9X]\b'
cat ip.txt | egrep '\<[0-9]{17}[0-9X]\>'

4. find

  • 按照需求查找文件
  • 语法格式:
# 按照文件类型查找
find /data -type 类型
                  f:普通文件
                  d:目录
                  l:软连接
                  b:块设备
                  c:字符设备

# 按照文件名称查找
find /data -name "a.txt"
           -iname(不区分大小写)

# 按照文件名称查找(不区分大小写),按照深度等级1级目录查找
find /data -maxdepth 1 -iname "a.txt"

# 按照文件大小查找
find /data -size +10M  查找大于10M的文件
                 -10M  查找小于10M的文件
                  10M  查找等于10M的文件

# 按照文件修改时间查找
find /data -mtime +7  查找7天前修改的文件
                  -7  查找7天内修改的文件

# 按照inode号码查找
find /data -inum 363225116

# find命令默认是并且关系,如果需要使用“或者”关系查找加 -or 参数

4.1. find结合|xargs使用

  • |xargs :前面的find查询输出结果默认会放到命令后面
  • xargs:默认以空格分隔,-n以列进行显示
find /data -name "a.txt" |xargs cat
# 注意:xargs后面的命令不支持别名
4.1.1. 案例
  • find命令查询的结果拷贝到/opt目录下
# 指定位置需加-i参数,insert插入
find /data -name "a.txt" |xargs -i cp {} /opt/

# cp -t 参数可以将源文件写后面
find /data -name "a.txt" |xargs cp -t /opt/
  • 将find命令查询的结果打包压缩
find /data -name "a.txt" |xargs tar a.tar.gz

4.2. find结合exec使用

  • -exec:前面的find查询输出结果默认会放到{}中,注意:一次只传递一个参数
find /data -name "a.txt" -exec cat {} \;
# 注意:-exec后面的命令不支持别名
4.2.1. 案例
  • find命令查询的结果拷贝到/opt目录下
find /data -name "a.txt" -exec cp {} /opt/ \;
  • 将find命令查询的结果打包压缩
find /data -name "a.txt" -exec tar zcf a.tar.gz {} \;

# 注意,-exec一次只会传递一个参数,所以只要在结尾添加 +
find /data -name "a.txt" -exec tar zcf a.tar.gz {} +

    5. 三剑客sed

    sed所有操作默认不会真正执行,都是假装运行,但是加上 -i 参数,那就是真正的操作,真正的修改

    5.1. sed删除行

    #删除第N行
    sed 'Nd' file
    
    #删除第N~M行
    sed 'N,Md' file
    
    #删除最后一行
    sed '$d' file
    
    #删除包含'cat'的行
    sed '/cat/d' file
    
    #删除包含A和B的行
    sed -r '/A|B/d' file
    
    #去掉/etc/ssh/sshd.config文件中的空行或注释行
    sed -r '/^$|^#/d' /etc/ssh/sshd.config

    5.2. sed添加行

    #在第4行前添加test
    sed '4i test' file
    
    #在第4行后添加test
    sed '4a test' file
    
    #将第5行的内容替换为test(常用)
    sed '4c test' file
    
    #将指定行保存到新文件1.txt中
    sed '3w 1.txt' file
    
    #在最后一行添加test
    sed '$a test' file
    
    #在以ccat开头的行前添加test
    sed '/^ccat/i test' file
    
    #在以ccat开头的行后添加test
    sed '/^ccat/a test' file

    5.3. sed替换

    sed -n取消默认输出
    
    #全局替换
    sed 's#原字符串#替换字符串#g' file
    
    #只在第3行全局替换
    sed -n '3s#原字符串#替换字符串#gp' file
    
    #只在3-6行全局替换
    sed -n '3,6s#原字符串#替换字符串#gp' file
    
    #只在包含xx的行全局替换
    sed -n '/xx/s#原字符串#替换字符串#gp' file
    
    #只在包含xx到包含yy的行之间全局替换
    sed -n '/xx/,/yy/s#原字符串#替换字符串#gp' file
    
    #将3到7行注释
    sed -n '3,7s/^/#/gp' file

    5.4. sed修改前先备份

    sed -i.bak 's/原字符串/替换字符串/g' file

    5.5. sed输出指定行

    sed -n取消默认输出
    sed -r支持扩展正则
    
    #sed输出第3行
    sed -n '3p' file
    
    #sed输出第3行到行尾
    sed -n '3,$p' file
    
    #sed输出第3行和第6行
    sed -n '3p;6p' file
    
    #sed输出包含test的行
    sed -n '/test/p' file
    sed -n '/test/Ip' file   #不区分大小写
    
    #sed输出包含test和ceshi的行,-r参数表示支持扩展的正则表达式,默认支持基础正则
    sed -rn '/test|ceshi/p' file
    
    #sed输出包含test的行到包含ceshi的行
    sed -n '/test/,/ceshi/p' file

    5.6. sed反向引用

    #后面的##之间调用前面##之间的内容,先通过正则匹配出来并加上()分组,\1表示第一组,\2表示第二组
    echo {1..10} | sed -r 's#(.*)#<\1>#g'
    <1 2 3 4 5 6 7 8 9 10>
    
    反向引用,取出某一行中的某部分内容
    通过反向引用取出ip地址
    ip a s ens33 | sed -n '3p'
        inet 10.0.0.210/24 brd 10.0.0.255 scope global noprefixroute ens33
    
    ip a s ens33 | sed -n '3p' | sed -r 's#^.*et (.*)/.*$#\1#g'
    
    #将/etc/passwd文件内容中第一列和最后一列内容调换位置
    root:x:0:0:root:/root:/bin/bash
    
    sed -r 's#(^.*)(:x.*:)(.*$)#\3\2\1#g' /etc/passwd

    6. 三剑客awk

    6.1. awk输出文件内容

    awk '{print}' file
    awk '{print $0}' file

    6.2. awk输出指定行

    #输出第3行
    awk 'NR==3' file
    
    #输出第3行到第5行
    awk 'NR==3,NR==5' file
    awk 'NR>=3 && NR<=5' file
    
    #输出包含test和ceshi的行
    awk '/test|ceshi/' file
    
    # awk输出/etc/passwd最后一列
    # 默认是以'空格'作为块分割,-F指定分隔符号
    awk -F ':' '{print $NF}' /etc/passwd
    
    # 输出/etc/passwd最后一列等于bash的行
    awk -F "/" '$NF=="bash"' /etc/passwd
    
    # 输出/etc/passwd最后一列包含字母n的行
    awk -F "/" '$NF ~ /^n/' /etc/passwd
    
    # 输出/etc/passwd第三列数字小于5的行
    awk -F: '$3<5' /etc/passwd
    
    # 输出/etc/passwd第三列等于root的行
    awk -F: '$1=="root"' /etc/passwd

    6.3. awk输出指定列

    默认是以'空格'作为块分割,-F指定分隔符号
    
    # 输出第一列
    awk -F":" '{print $1}' /etc/passwd
    
    # 输出第三列和第四列
    awk -F":" '{print "第三列: "$3,"\t第四列: "$4}' /etc/passwd
    
    # 输出第一行中的第三列和第四列
    awk -F":" 'NR==1{print "第三列: "$3,"\t第四列: "$4}' /etc/passwd
    
    # 输出最后一列,NF存放的是最后一列的列号,$NF 表示取出最后一列
    awk -F':' '{print $NF}' /etc/passwd
    
    # 输出倒数第二列
    awk -F':' '{print $(NF-1)}' /etc/passwd

    6.4. awk消除空白行

    awk NF test

    6.5. awk输出前N列

    awk -F':' 'NF=5' /etc/passwd

    6.6. awk输出/etc/passwd每一行内容,加上行号

    [root@zbl ~]# awk '{print NR,$0}' /etc/passwd
    
    NR 表示行号
    $0 表示一整行内容

    6.7. awk输出ip地址

    [root@zbl ~]# ip addr show ens33 | awk 'NR==3' | awk '{print $2}' | awk -F'/' '{print $1}'
    10.0.0.200
    
    [root@zbl ~]# ip addr show ens33 | awk 'NR==3' | awk -F '[ /]' '{print $6}'
    10.0.0.200
    
    [root@zbl ~]# ip addr show ens33 | awk 'NR==3' | awk -F '[ /]+' '{print $3}'
    10.0.0.200
    
    [root@zbl ~]# ip addr show ens33 | awk -F '[ /]+' 'NR==3{print $3}'
    10.0.0.200

    6.8. awk过滤某一列中包含/不包含的内容

    过滤/etc/passwd中第三列包含1或者2的行
    $3 表示第三列
    ~ 表示包含
    !~ 表示不包含
    // 表示包含的内容
    [root@zbl ~]# awk -F: '$3 ~ /^[12]/' /etc/passwd
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    
    # 过滤/etc/passwd中第三列以0到3结尾的,显示第一列和第三列内容
    条件:第3列以0到3结尾(取行)
    动作:显示第1列和第3列(取列)
    [root@zbl ~]# awk -F: '$3~/[0-3]$/ {print $1,$3}' /etc/passwd
    root 0
    bin 1
    
    # 过滤passwd中第3列大于0小于1000内容,显示第1列和第3列
    条件:第3列大于0小于1000(取行)
    
    [root@zbl ~]# awk -F: '$3>0 && $3<1000{print $1,$3}' /etc/passwd | column -t
    bin              1
    daemon           2
    
    # 过滤出网卡配置文件中的ip地址
    [root@zbl ~]# awk -F= '/IPADDR/{print $2}' /etc/sysconfig/network-scripts/ifcfg-ens33
    10.0.0.200

    6.9. awk计算功能

    BEGIN{}  # 在读取文件内容之前执行
    END{}    # 在读取文件内容之后执行
    
    # 修改awk变量
    awk 'BEGIN{FS=":"} NR==1{print $1}' /etc/passwd

    6.10. awk统计数量

    # 统计/etc/passwd有多少行
    [root@zbl ~]# awk '{i++} END{print i}' /etc/passwd
    22
    
    # 统计/etc/passwd可登录的用户数量
    [root@zbl ~]# awk '/bash$/' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    zbl:x:1000:1000::/home/zbl:/bin/bash
    [root@zbl ~]# awk '/bash$/ {i++} END{print i}' /etc/passwd
    2
    
    # 统计/etc/services文件中空行的数量
    [root@zbl ~]# awk '/^$/ {i++} END{print i}' /etc/services 
    17
    
    # 统计access.log中一共用了多少流量
    第一列:IP地址
    第四列:时间
    第十列:流量(字节)
    
    awk '{sum=sum+$10} END{print sum/1024^3"GB"}' access.log


    网站公告

    今日签到

    点亮在社区的每一天
    去签到