当前位置: 首页 > article >正文

day020-sed和find

文章目录

  • 1. sed
    • 1.1 查找、过滤文本
      • 1.1.1 根据行号取行
      • 1.1.2 根据行号取范围
      • 1.1.3 过滤出指定行
      • 1.1.4 过滤出指定范围内容
    • 1.2 替换文件内容
      • 1.2.1 将文件中虚拟用户命令解释器替换成/bin/bash
      • 1.2.2 修改原文件并备份
      • 1.2.3 为每行开头加上#
    • 1.3 反向引用(后向引用)
      • 1.3.1 将用户名和命令解释器调换位置
      • 1.3.2 将日志中时间格式改为年月日
    • 1.4 删除
      • 1.4.1 按照行号删除
      • 1.4.2 将空行或以#开头的行删除
    • 1.5 增加数据
      • 1.5.1 a
      • 1.5.2 i
      • 1.5.3 c
    • 1.6 案例:排除/删除sshd配置文件中的空行或注释行(不需要真的删除)
  • 2. find
    • 2.1 find基础使用
      • 2.1.1 找出/etc下以.conf结尾的文件
      • 2.1.2 找出/etc下大于100k的文件
      • 2.1.3 找出/var/log目录下以.log结尾7天前的文件
    • 2.2 find进阶使用
      • 2.2.1 在/etc下找出以.conf结尾的文件,找出这些文件中包含root或oldboy的行
      • 2.2.2 在/etc下找出以.conf结尾的文件,将这些文件打包
      • 2.2.3 找出/var/log目录下以.log结尾的文件复制到/backup/logs目录
  • 3. 踩坑记录
    • 3.1 find: 遗漏“-exec”的参数
  • 4. 思维导图

1. sed

sed格式:

sed 选项 脚本 文件

  • sed(Stream Editor)是 Linux/Unix 下的流式文本编辑器,用于对文本进行查找、替换、删除、插入等操作,支持正则表达式。
  • sed“流式编辑”(Stream Editing)特性体现在它处理文本的方式上:逐行读取、即时处理、无需加载整个文件到内存
  • grepawk 在处理文本时,默认也是逐行读取数据(流式处理)

1.1 查找、过滤文本

  • sed默认是自动打印模式,从输入(stdin或文件)逐行读取数据,并输出原文件数据。
  • -n:取消自动打印模式

1.1.1 根据行号取行

  • 脚本选项p:print,将结果输出
[root@oldboy99-Kylin ~/oldboy]# sed -n '1p' passwd
root:x:0:0:root:/root:/bin/bash

1.1.2 根据行号取范围

[root@oldboy99-Kylin ~/oldboy]# sed -n '1,5p' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

1.1.3 过滤出指定行

  • -r:使用扩展正则表达式
  • 过滤出包含root或oldboy的行
[root@oldboy99-Kylin ~/oldboy]# sed -rn '/root|oldboy/p' passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
oldboy:x:1000:1000::/home/oldboy:/bin/bash

1.1.4 过滤出指定范围内容

  • 按时间范围过滤出日志内容
[root@oldboy99-Kylin ~/oldboy]# sed -n '/11:05:00/,/11:06:00/p' access.log |head -n 1
114.84.238.226 - - [22/Nov/2015:11:05:00 +0800] "GET /online/oldboyonline/order/mapInfoWindow.css HTTP/1.1" 200 608 "http://www.papaonline.com.cn/online/oldboyonline/order/orderNow.jsp" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36"
[root@oldboy99-Kylin ~/oldboy]# sed -n '/11:05:00/,/11:06:00/p' access.log |wc -l
3366
  • 取出日志中从第一行到11:30范围的日志,并取出第一列,统计最多的ip,取前五名
[root@oldboy99-Kylin ~/oldboy]# sed -n '1,/11:30:00/p' access.log |awk '{print $1}' |sort |uniq -c |sort -k1nr |head -55883 112.64.171.985574 58.220.223.62957 116.216.0.60799 114.83.184.139792 121.235.250.231
# 用awk过滤
[root@oldboy99-Kylin ~/oldboy]# awk 'NR==1,/11:30:00/{print $1}' access.log |sort |uniq -c |sort -k1nr |head -55883 112.64.171.985574 58.220.223.62957 116.216.0.60799 114.83.184.139792 121.235.250.231

1.2 替换文件内容

  • 脚本选择:s###g
  • s:substitute,替换
  • g:global,整行替换
  • 中间的分隔符可以换成其他的符号:@、/等

1.2.1 将文件中虚拟用户命令解释器替换成/bin/bash

  • 基础替换不会改变文件内容
  • 替换操作时需要查看输出结果,所以不要加-n;也不需要指定输出,不要加p
[root@oldboy99-Kylin ~/oldboy]# sed  's#/sbin/nologin#/bin/bash/#g' passwd |head -5
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/bash/
daemon:x:2:2:daemon:/sbin:/bin/bash/
adm:x:3:4:adm:/var/adm:/bin/bash/
lp:x:4:7:lp:/var/spool/lpd:/bin/bash/
  • -i:in-place,直接修改文件内容
[root@oldboy99-Kylin ~/oldboy]# sed -i 's#/sbin/nologin#/bin/bash/#g' passwd 
[root@oldboy99-Kylin ~/oldboy]# head -n 5 passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/bash/
daemon:x:2:2:daemon:/sbin:/bin/bash/
adm:x:3:4:adm:/var/adm:/bin/bash/
lp:x:4:7:lp:/var/spool/lpd:/bin/bash/
[root@oldboy99-Kylin ~/oldboy]# grep '/sbin/nologin' passwd
[root@oldboy99-Kylin ~/oldboy]# 

1.2.2 修改原文件并备份

  • -i[扩展名]:直接修改文件(如果指定扩展名则备份文件)
[root@oldboy99-Kylin ~/oldboy]# ll
-rw-r--r-- 1 root root     2006  526 14:33 passwd
[root@oldboy99-Kylin ~/oldboy]# sed -i.bak 's#/sbin/nologin#/bin/bash#g' passwd 
[root@oldboy99-Kylin ~/oldboy]# ll
-rw-r--r-- 1 root root     1874  526 14:34 passwd
-rw-r--r-- 1 root root     2006  526 14:33 passwd.bak
[root@oldboy99-Kylin ~/oldboy]# grep '/sbin/nologin' passwd
[root@oldboy99-Kylin ~/oldboy]# 

1.2.3 为每行开头加上#

[root@oldboy99-Kylin ~/oldboy]# sed 's@^@#@g' passwd
#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/bin/bash
#daemon:x:2:2:daemon:/sbin:/bin/bash
#adm:x:3:4:adm:/var/adm:/bin/bash
……

1.3 反向引用(后向引用)

  • 通过正则表达式把要处理的内容进行分组,在后面通过数字引用进行处理

1.3.1 将用户名和命令解释器调换位置

[root@oldboy99-Kylin ~/oldboy]# sed -r 's#^(.+)(:x:.+:)(/.+)$#\3\2\1#g' passwd |head -5
/bin/bash:x:0:0:root:/root:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon
/sbin/nologin:x:3:4:adm:/var/adm:adm
/sbin/nologin:x:4:7:lp:/var/spool/lpd:lp

1.3.2 将日志中时间格式改为年月日

  • 过滤[]时要加反斜线
[root@oldboy99-Kylin ~/oldboy]# head -1 access.log 
101.226.61.184 - - [22/Nov/2015:11:02:00 +0800] "GET /mobile/sea-modules/gallery/zepto/1.1.3/zepto.js HTTP/1.1" 200 24662 "http://m.oldboyedu.com.cn/mobile/theme/oldboy/home/index.html" "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; HUAWEI CRR-UL00 Build/HUAWEICRR-UL00) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025478 Mobile Safari/533.1 MicroMessenger/6.3.7.51_rbb7fa12.660 NetType/3gnet Language/zh_CN"
[root@oldboy99-Kylin ~/oldboy]# sed -r 's#^(.+\[)([0-9]+)/([A-Z][a-z]+/)(2015)(:.+)$#\1\4/\3\2\5#g' access.log |head -1
101.226.61.184 - - [2015/Nov/22:11:02:00 +0800] "GET /mobile/sea-modules/gallery/zepto/1.1.3/zepto.js HTTP/1.1" 200 24662 "http://m.oldboyedu.com.cn/mobile/theme/oldboy/home/index.html" "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; HUAWEI CRR-UL00 Build/HUAWEICRR-UL00) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025478 Mobile Safari/533.1 MicroMessenger/6.3.7.51_rbb7fa12.660 NetType/3gnet Language/zh_CN"

1.4 删除

1.4.1 按照行号删除

  • 脚本参数d:删除
  • 不会影响原文件
[root@oldboy99-Kylin ~/oldboy]# sed '1d' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
……
# 按照行号范围删除
[root@oldboy99-Kylin ~/oldboy]# sed '1,5d' passwd 
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
……

1.4.2 将空行或以#开头的行删除

[root@oldboy99-Kylin ~/oldboy]# sed -r '/^$|^#/d' passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
……

1.5 增加数据

脚本参数说明
aappend,在指定的行后面追加一行
iinsert,在指定的行上面追加一行
creplace,把指定的行内容替换掉

1.5.1 a

[root@oldboy99-Kylin ~/oldboy]# sed '1a 孙克旭' passwd 
root:x:0:0:root:/root:/bin/bash
孙克旭
bin:x:1:1:bin:/bin:/sbin/nologin
……

1.5.2 i

[root@oldboy99-Kylin ~/oldboy]# sed '1i 孙克旭' passwd 
孙克旭
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
……

1.5.3 c

[root@oldboy99-Kylin ~/oldboy]# sed '1c 孙克旭' passwd 
孙克旭
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
……

1.6 案例:排除/删除sshd配置文件中的空行或注释行(不需要真的删除)

  • grep:
[root@oldboy99-Kylin ~]# grep -Ev '^$|^#' /etc/ssh/sshd_config
Port 12345
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
……
  • sed:
  • !:取反,注意符号的位置
[root@oldboy99-Kylin ~]# sed -rn '/^$|^#/!p' /etc/ssh/sshd_config
Port 12345
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
……
############################################
[root@oldboy99-Kylin ~]# sed -r '/^$|^#/d' /etc/ssh/sshd_config
Port 12345
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
……
  • awk:
[root@oldboy99-Kylin ~]# awk '!/^$|^#/' /etc/ssh/sshd_config
Port 12345
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
……

2. find

  • 根据指定的目录查找内容(文件、目录)
选项说明
-typef:文件
d:目录
-name文件名
-size文件大小,单位k(小写)、M(大写)、G(大写)
-mtime文件创建时间,+7:7天以前

2.1 find基础使用

2.1.1 找出/etc下以.conf结尾的文件

[root@oldboy99-Kylin ~]# find /etc/ -type f -name '*.conf'
/etc/resolv.conf
/etc/dnf/protected.d/systemd.conf
/etc/dnf/protected.d/sudo.conf
/etc/dnf/protected.d/dnf.conf
……

2.1.2 找出/etc下大于100k的文件

[root@oldboy99-Kylin ~]# find /etc/ -type f -size +100k
/etc/pki/ca-trust/extracted/edk2/cacerts.bin
/etc/pki/ca-trust/extracted/java/cacerts
……

2.1.3 找出/var/log目录下以.log结尾7天前的文件

[root@oldboy99-Kylin ~]# find /var/log/ -type f -name '*.log' -mtime +7
/var/log/dracut.log
/var/log/.kylin-post-actions-nochroot.log
/var/log/anaconda/anaconda.log
……

2.2 find进阶使用

2.2.1 在/etc下找出以.conf结尾的文件,找出这些文件中包含root或oldboy的行

  • 是文件内容中包含……,不是文件名
  • 管道的作用是将左侧的命令结果作为右侧的命令输入
  • 这里需要将文件路径作为grep的参数,而不是数据输入,所以使用xargs将左侧结果按行转换成右侧命令的参数
  • grep 的颜色输出在通过管道或 xargs 时会默认被禁用
[root@oldboy99-Kylin ~]# find /etc/ -type f -name '*.conf' |xargs grep -E 'root|oldboy' --color=auto
/etc/libreport/events.d/bugzilla_anaconda_event.conf:			sed 's/^.*rootpw.*$/<auto-removed line containing rootpw>/' -i $sf
/etc/libreport/events.d/collect_dnf.conf:            if [[ $username != "root" ]]; then
/etc/libreport/events.d/abrt_event.conf:# Example: if you want all users (not just root) to be able to see some problems:
/etc/libreport/events.d/smart_event.conf:# Access to /dev/sda usually requires root.
……

[root@oldboy99-Kylin ~]# grep -E 'root|oldboy' `find /etc/ -type f -name '*.conf'`
/etc/libreport/events.d/bugzilla_anaconda_event.conf:			sed 's/^.*rootpw.*$/<auto-removed line containing rootpw>/' -i $sf
/etc/libreport/events.d/collect_dnf.conf:            if [[ $username != "root" ]]; then
/etc/libreport/events.d/abrt_event.conf:# Example: if you want all users (not just root) to be able to see some problems:
/etc/libreport/events.d/smart_event.conf:# Access to /dev/sda usually requires root.
……

[root@oldboy99-Kylin ~]# find /etc/ -type f -name '*.conf' -exec grep -E --color=auto 'root|oldboy' {}  \; sed 's/^.*rootpw.*$/<auto-removed line containing rootpw>/' -i $sfif [[ $username != "root" ]]; then
# Example: if you want all users (not just root) to be able to see some problems:
# Access to /dev/sda usually requires root.
# Therefore we run it as post-create event, thus: under root.# Can't do it as analyzer step, non-root can't read log.
rootpw
……
  • -exec的方式显示的结果不明显

2.2.2 在/etc下找出以.conf结尾的文件,将这些文件打包

[root@oldboy99-Kylin ~]# find /etc/ -type f -name '*.conf' |xargs tar zcf /backup/etc-conf.tar.gz 
tar: 从成员名中删除开头的“/”
tar: 从硬连接目标中删除开头的“/”

[root@oldboy99-Kylin ~]# tar zcf /backup/etc-conf.tar.gz `find /etc/ -type f -name '*.conf'`
tar: 从成员名中删除开头的“/”
tar: 从硬连接目标中删除开头的“/”

# 错误方法:
[root@oldboy99-Kylin ~]# find /etc/ -type f -name '*.conf' -exec tar zcf /backup/etc-conf.tar.gz {} \;
tar: 从成员名中删除开头的“/”
tar: 从成员名中删除开头的“/”
tar: 从成员名中删除开头的“/”
……
[root@oldboy99-Kylin /backup]# tar tf etc-conf.tar.gz 
etc/pulse/daemon.conf
  • find的结果会进入{}内;
  • 如果有10个文件,tar命令执行了10次,而且每次都会覆盖原压缩包,所以最后的压缩包只有一个文件

[root@oldboy99-Kylin ~]# find /etc/ -type f -name '*.conf' -exec tar zcf /backup/etc-conf.tar.gz {} +
tar: 从成员名中删除开头的“/”
tar: 从硬连接目标中删除开头的“/”
  • +:批量处理模式
    会让 find 将匹配到的所有文件一次性传递给后面的命令

2.2.3 找出/var/log目录下以.log结尾的文件复制到/backup/logs目录

  • 问题和上面的tar一样,是参数位置问题
  • -t:后面指定目标目录;将源文件复制到该目录中
[root@oldboy99-Kylin ~]# find /var/log/ -type f -name '*.log' |xargs cp -t /backup/logs/
cp: 不会以'/var/log/dnf.librepo.log' 覆盖刚创建的'/backup/logs/dnf.librepo.log'
cp: 不会以'/var/log/hawkey.log' 覆盖刚创建的'/backup/logs/hawkey.log'

[root@oldboy99-Kylin ~]# yes |cp `find /var/log/ -type f -name '*.log'` /backup/logs/ 
cp:是否覆盖'/backup/logs/sssd_implicit_files.log'? 
cp:是否覆盖'/backup/logs/sssd.log'? 
cp:是否覆盖'/backup/logs/sssd_nss.log'
  • yes:自动对所有的询问回答yes
  • 或者不使用别名cp:\cp

find /var/log/ -type f -name '*.log' -exec cp {} /backup/logs/ \;

3. 踩坑记录

3.1 find: 遗漏“-exec”的参数

[root@oldboy99-Kylin ~]# find /var/log/ -type f -name '*.log' -exec cp {} /backup/logs/ +
find: 遗漏“-exec”的参数
  • -exec+ 参数必须直接放在 {} 后面

4. 思维导图

【金山文档】 思维导图 https://www.kdocs.cn/l/co3I7PtpTYQX

http://www.lryc.cn/news/2386615.html

相关文章:

  • OpenGL Chan视频学习-4 Vertex Buffers and Drawing a Triangle in OpenGL
  • 数据库事务的四大特性(ACID)
  • 网络安全全知识图谱:威胁、防护、管理与发展趋势详解
  • FreeRTOS 在物联网传感器节点的应用:低功耗实时数据采集与传输方案
  • 解决 iTerm2 中 nvm 不生效的问题(Mac 环境)
  • Linux环境下基于Docker安装 PostgreSQL数据库并配置 pgvector
  • (9)-java+ selenium->元素定位之By name
  • 深浅拷贝?
  • Beckhoff PLC 功能块 FB_CTRL_ACTUAL_VALUE_FILTER (模拟量滤波)
  • Mysql在SQL层面的优化
  • JVM规范之栈帧
  • 【C++指南】string(四):编码
  • 深度学习之序列建模的核心技术:LSTM架构深度解析与优化策略
  • AI量化交易是什么?它是如何重塑金融世界的?
  • 分布式事务处理方案
  • CVE-2024-36467 Zabbix权限提升
  • Dify中的自定义模型插件开发例子:以xinference为例
  • crud方法命名示例
  • 尚硅谷redis7 33-36 redis持久化之RDB优缺点及数据丢失案例
  • No such file or directory: ‘ffprobe‘
  • 计算机网络-WebSocket/DNS/Cookie/Session/Token/Jwt/Nginx
  • 功能“递归模式”在 C# 7.3 中不可用,请使用 8.0 或更高的语言版本的一种兼容处理方案
  • 第4章-操作系统知识
  • 将网页带格式转化为PDF
  • 【ArcGIS】ArcGIS AI 助手----复现
  • 使用 FFmpeg 将视频转换为高质量 GIF(保留原始尺寸和帧率)
  • 《Java vs Go vs C++ vs C:四门编程语言的深度对比》
  • 充电枪IEC62196/EN 62196测试内容
  • 有效的字母异位符--LeetCode
  • SAP ERP 系统拆分的七大挑战