恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Shell脚本编程开发实战(四):常用工具与grep文本搜索实战
首页
资讯中心
/
Shell脚本编程开发实战(四):常用工具与grep文本搜索实战
Shell脚本编程开发实战(四):常用工具与grep文本搜索实战
发布时间:2026/9/10 11:40:46
Shell脚本编程开发实战四常用工具与grep文本搜索实战系列文章目录第一篇Shell入门与命令基础第二篇Shell变量与条件测试第三篇变量高级用法与函数详解第四篇常用工具与grep文本搜索实战本文导读本文是Shell脚本编程系列的第四篇涵盖第7-8章内容。我们将系统学习Linux下最强大的文件查找工具find命令的各种用法掌握xargs管道处理、文件压缩归档技巧然后深入文本搜索神器grep和egrep的正则表达式实战。所有命令均在远程Ubuntu 24.04服务器上真实执行输出均为实际运行结果。我们准备了测试文件文本文件、日志文件、配置文件、不同大小的二进制文件用于演示。实操环境系统Ubuntu 24.04.4 LTS内核6.8.0-106-generic测试目录/tmp/shell_test/目录一、find命令详解第7章1.1 基本查找按名称和类型1.2 按大小、时间、权限查找1.3 高级用法-exec与xargs二、locate、whereis、which对比三、文件压缩与归档3.1 tar归档与压缩3.2 gzip单文件压缩3.3 bzip2高压缩比四、grep文本搜索第8章4.1 grep基本用法4.2 grep常用选项4.3 正则表达式五、egrep扩展正则表达式六、实战场景应用6.1 日志分析6.2 配置文件搜索6.3 多文件搜索与进程查找总结思考题一、find命令详解第7章find是Linux下最强大的文件查找命令支持按名称、类型、大小、时间、权限等多种条件搜索并可对结果执行操作。1.1 基本查找按名称和类型# 按文件名查找find/tmp/shell_test-name*.sh# 忽略大小写find/tmp/shell_test-iname*.SH# 按文件类型查找f普通文件d目录find/tmp/shell_test-typeffind/tmp/shell_test-typed# 按扩展名查找find/tmp/shell_test-name*.logfind/tmp/shell_test-name*.txt实际输出 find by name /tmp/shell_test/test1.sh /tmp/shell_test/test2.sh /tmp/shell_test/str_proc.sh /tmp/shell_test/mylib.sh find by type (files) /tmp/shell_test/run.py /tmp/shell_test/test1.sh /tmp/shell_test/test2.sh /tmp/shell_test/sample.txt /tmp/shell_test/app.log /tmp/shell_test/subdir/data.log /tmp/shell_test/subdir/note.txt /tmp/shell_test/config.conf /tmp/shell_test/str_proc.sh /tmp/shell_test/mylib.sh find by type (directories) /tmp/shell_test /tmp/shell_test/subdir find by extension (*.log) /tmp/shell_test/app.log /tmp/shell_test/subdir/data.log解析-name支持通配符*、?、[]但需要用引号包裹防止Shell展开。-type常用值f普通文件、d目录、l符号链接、b块设备、c字符设备。1.2 按大小、时间、权限查找# 按大小查找find/tmp/shell_test-typef-size1M# 大于1MBfind/tmp/shell_test-typef-size-1k# 小于1KBfind/tmp/shell_test-typef-size1k-size-5M# 1KB到5MB之间# 按时间查找find/tmp/shell_test-typef-mmin-10# 10分钟内修改的find/tmp/shell_test-typef-mtime-1# 1天内修改的find/tmp/shell_test-typef-amin-5# 5分钟内访问的# 按权限查找find/tmp/shell_test-typef-perm/111# 可执行文件find/tmp/shell_test-typef-perm644# 权限为644的文件# 按用户查找find/tmp/shell_test-typef-userroot实际输出 find by size Files larger than 1M: /tmp/shell_test/large_file.bin Files between 1K and 5M: /tmp/shell_test/medium_file.bin find by time (last 10 min) /tmp/shell_test/run.py /tmp/shell_test/test1.sh /tmp/shell_test/test2.sh /tmp/shell_test/sample.txt /tmp/shell_test/app.log ... find by permissions Executable files: /tmp/shell_test/test1.sh /tmp/shell_test/test2.sh /tmp/shell_test/str_proc.sh Files with 644 permission: /tmp/shell_test/run.py /tmp/shell_test/sample.txt /tmp/shell_test/app.log ...解析大小单位b512字节块、c字节、kKB、MMB、GGB。表示大于-表示小于时间选项-mtime修改天数、-mmin修改分钟、-atime/-amin访问时间、-ctime/-cmin状态变更时间权限匹配-perm 644精确匹配-perm /111匹配任意可执行位1.3 高级用法-exec与xargsfind的-exec选项可以对查找结果执行任意命令xargs则将结果作为参数传递给后续命令# -exec 对每个文件执行命令\;表示逐个执行find/tmp/shell_test-name*.sh-execls-l{}\;# -exec 对所有文件一次执行表示批量find/tmp/shell_test-name*.log-execwc-l{}# xargs 组合使用find/tmp/shell_test-name*.sh|xargsls-l# xargs 处理含空格文件名-print0 -0find/tmp/shell_test-name*.sh-print0|xargs-0-I{}sh-c\echo Script: {} ($(wc -l {}) lines)# find 删除匹配文件find/tmp/shell_test-name*.bin-execrm-v{}\;实际输出 find -exec -rwxr-xr-x 1 root root 33 Sep 9 23:42 /tmp/shell_test/test1.sh -rwxr-xr-x 1 root root 33 Sep 9 23:42 /tmp/shell_test/test2.sh -rwxr-xr-x 1 root root 899 Sep 9 23:44 /tmp/shell_test/str_proc.sh -rw-r--r-- 1 root root 796 Sep 9 23:45 /tmp/shell_test/mylib.sh xargs with -print0 Script: /tmp/shell_test/test1.sh (2 lines) Script: /tmp/shell_test/test2.sh (2 lines) Script: /tmp/shell_test/str_proc.sh (38 lines) Script: /tmp/shell_test/mylib.sh (59 lines) find and delete removed /tmp/shell_test/medium_file.bin removed /tmp/shell_test/large_file.bin removed /tmp/shell_test/small_file.bin解析\;对每个文件单独执行一次命令效率较低将所有文件名一次性传给命令效率更高xargs比-exec更灵活可以和任意命令组合-print0xargs -0用NULL分隔符处理含空格/特殊字符的文件名是最安全的做法二、locate、whereis、which对比四个查找命令各有侧重# which在PATH中查找可执行文件位置whichbash# /usr/bin/bashwhichpython3# /usr/bin/python3whichgrep# /usr/bin/grep# whereis查找二进制文件、源码、man手册whereisbash# bash: /usr/bin/bash /usr/share/man/man1/bash.1.gzwhereisgrep# grep: /usr/bin/grep /usr/share/man/man1/grep.1.gz# locate从预建数据库快速查找需先updatedbupdatedblocate-ishell_test实际输出 which /usr/bin/bash /usr/bin/python3 /usr/bin/grep /usr/bin/find whereis bash: /usr/bin/bash /usr/share/man/man1/bash.1.gz grep: /usr/bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz python3: /usr/bin/python3 /usr/lib/python3 /etc/python3 /usr/share/python3 /usr/share/man/man1/python3.1.gz四者对比命令搜索范围速度实时性典型用途which$PATH极快实时查找命令的安装位置whereis系统标准目录快实时查找二进制源码man手册locate全文件系统数据库极快需updatedb更新快速模糊查找文件路径find指定目录实时遍历较慢实时精确条件查找操作解析locate依赖预先构建的文件数据库通常由cron定期updatedb更新速度极快但可能找不到最新创建的文件。find实时遍历文件系统结果准确但速度较慢适合精确查找。三、文件压缩与归档3.1 tar归档与压缩tar是Linux最常用的归档工具配合压缩算法实现打包压缩# 创建tar归档不压缩tar-cvfarchive.tar sample.txt config.conf app.log# 查看归档内容tar-tvfarchive.tar# 创建gzip压缩归档最常用tar-czvfarchive.tar.gz sample.txt config.conf app.log# 创建bzip2压缩归档压缩率更高tar-cjvfarchive.tar.bz2 sample.txt config.conf app.log# 解压gzip归档tar-xzvfarchive.tar.gz# 解压到指定目录tar-xzvfarchive.tar.gz-C/target/dir/实际输出 tar (archive) sample.txt config.conf app.log Archive contents: -rw-r--r-- root/root 164 2026-09-09 23:42 sample.txt -rw-r--r-- root/root 219 2026-09-09 23:42 config.conf -rw-r--r-- root/root 626 2026-09-09 23:42 app.log Archive size: 10K tar gzip Compressed archive size: 673 Uncompressed size: 10K Compression ratio: 15.2x tar bzip2 bzip2 archive size: 707tar选项速查表选项说明-c创建归档Create-x解压归档eXtract-t列出内容lisT-v显示详细信息Verbose-f指定文件名File-z使用gzip压缩-j使用bzip2压缩-J使用xz压缩解析gzip压缩速度最快、兼容性最好bzip2压缩率更高但速度较慢xz压缩率最高但速度最慢。日常备份推荐tar -czvfgzip需要极致压缩时用tar -cJvfxz。3.2 gzip单文件压缩# 压缩单个文件gzipsample_copy.txt# 生成 sample_copy.txt.gz# 解压gunzip sample_copy.txt.gz# 恢复 sample_copy.txt# 查看压缩文件内容不解压zcat sample_copy.txt.gz实际输出Compressed file: 156 Decompress: Restored: 164解析gzip直接在原文件后加.gz后缀并删除原文件。如需保留原文件使用gzip -k。zcat/zgrep可以直接操作压缩文件无需解压。3.3 bzip2高压缩比# bzip2压缩比gzip压缩率更高bzip2filename bunzip2 filename.bz2# tar bzip2tar-cjvfarchive.tar.bz2 file1 file2tar-xjvfarchive.tar.bz2实际输出bzip2 archive size: 707解析本次测试中bzip2707字节比gzip673字节略大这是因为文件本身较小bzip2的头部开销占比更大。对于大文件bzip2通常能比gzip多压缩10%-20%。四、grep文本搜索第8章grepGlobal Regular Expression Print是Linux下最强大的文本搜索工具支持基本正则表达式。4.1 grep基本用法# 基本搜索grepHello/tmp/shell_test/sample.txtgrepShell/tmp/shell_test/sample.txt# 显示行号grep-nINFO/tmp/shell_test/app.log# 统计匹配行数grep-cERROR/tmp/shell_test/app.log# 反向匹配显示不包含模式的行grep-vINFO/tmp/shell_test/app.log# 忽略大小写grep-ihello/tmp/shell_test/sample.txt实际输出 Basic grep Search Hello in sample.txt: Hello World Hello Shell grep with -n (line numbers) 1:2024-01-15 10:23:45 INFO Application started 3:2024-01-15 10:24:02 INFO Configuration loaded successfully 7:2024-01-15 10:27:00 INFO Retrying connection 8:2024-01-15 10:27:05 INFO Database connected 11:2024-01-15 10:29:00 INFO Request completed 13:2024-01-15 10:30:15 INFO Application shutdown grep with -c (count) INFO lines: 6 ERROR lines: 3 WARNING lines: 2 grep with -v (invert match) Lines NOT containing INFO: 2024-01-15 10:24:01 DEBUG Loading configuration 2024-01-15 10:25:30 WARNING Memory usage high: 85% 2024-01-15 10:26:15 ERROR Failed to connect database 2024-01-15 10:26:20 ERROR Connection timeout 2024-01-15 10:28:00 DEBUG Processing user request 2024-01-15 10:28:30 WARNING Slow query detected 2024-01-15 10:30:00 ERROR Null pointer exception解析-n显示行号便于定位-c只返回匹配数量不显示内容适合脚本中判断-v反向匹配常用于过滤日志如排除DEBUG信息-i忽略大小写在搜索不确定大小写的内容时很有用。4.2 grep常用选项# -r 递归搜索目录grep-rHello/tmp/shell_test/# -l 只显示包含匹配的文件名grep-rlHello/tmp/shell_test/# -o 只输出匹配的部分grep-oERROR.*/tmp/shell_test/app.log# -A/-B/-C 显示上下文行grep-A1ERROR/tmp/shell_test/app.log# 匹配行后1行grep-B1ERROR/tmp/shell_test/app.log# 匹配行前1行grep-C1WARNING/tmp/shell_test/app.log# 匹配行前后各1行# -e 多模式匹配grep-eERROR-eWARNING/tmp/shell_test/app.log# -w 精确匹配单词grep-wINFO/tmp/shell_test/app.log实际输出 -r (recursive) /tmp/shell_test/run.py:print(Hello from Python) /tmp/shell_test/sample.txt:Hello World /tmp/shell_test/sample.txt:Hello Shell -l (filenames only) /tmp/shell_test/run.py /tmp/shell_test/sample.txt /tmp/shell_test/str_proc.sh -o (only matching) ERROR Failed to connect database ERROR Connection timeout ERROR Null pointer exception -A 1 (after context) 2024-01-15 10:26:15 ERROR Failed to connect database 2024-01-15 10:26:20 ERROR Connection timeout 2024-01-15 10:27:00 INFO Retrying connection -- 2024-01-15 10:30:00 ERROR Null pointer exception 2024-01-15 10:30:15 INFO Application shutdown -C 1 (context) 2024-01-15 10:24:02 INFO Configuration loaded successfully 2024-01-15 10:25:30 WARNING Memory usage high: 85% 2024-01-15 10:26:15 ERROR Failed to connect database -- 2024-01-15 10:28:00 DEBUG Processing user request 2024-01-15 10:28:30 WARNING Slow query detected 2024-01-15 10:29:00 INFO Request completed解析-A/-B/-C是日志分析的利器——查看错误前后的上下文信息帮助快速定位问题原因。-o只输出匹配部分配合正则可以提取特定格式的数据如IP地址、时间戳。4.3 正则表达式grep支持基本正则表达式BRE# ^ 行首锚定grep^2024/tmp/shell_test/app.log# $ 行尾锚定grepshutdown$/tmp/shell_test/app.log# . 匹配任意单个字符grepW.rld/tmp/shell_test/sample.txt# [] 字符类grep[0-9][0-9]:[0-9][0-9]/tmp/shell_test/app.log# * 前一个字符出现0次或多次grepHello.*Script/tmp/shell_test/sample.txt# \b 单词边界grep\bINFO\b/tmp/shell_test/app.log实际输出 Anchor: ^ (line start) 2024-01-15 10:23:45 INFO Application started 2024-01-15 10:24:01 DEBUG Loading configuration 2024-01-15 10:24:02 INFO Configuration loaded successfully Anchor: $ (line end) 2024-01-15 10:30:15 INFO Application shutdown Dot . (any single char) Hello World Range [0-9] 2024-01-15 10:23:45 INFO Application started 2024-01-15 10:24:01 DEBUG Loading configuration 2024-01-15 10:24:02 INFO Configuration loaded successfully解析^和$是正则中最常用的锚定符^ERROR匹配以ERROR开头的行\.log$匹配以.log结尾的行。.匹配任意单个字符除换行.*组合表示匹配任意字符串。五、egrep扩展正则表达式egrep或grep -E支持扩展正则表达式ERE提供更强大的模式匹配能力# | 或运算egrepERROR|WARNING/tmp/shell_test/app.log# 前一个字符出现1次或多次egrep0/tmp/shell_test/config.conf# () 分组egrep(ERROR|WARNING)/tmp/shell_test/app.log# {n} 精确重复次数egrep[0-9]{4}-[0-9]{2}-[0-9]{2}/tmp/shell_test/app.log# 提取IP地址egrep-o([0-9]{1,3}\.){3}[0-9]{1,3}/tmp/shell_test/config.conf# 提取时间戳egrep-o[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/tmp/shell_test/app.log实际输出 egrep with | (OR) 2024-01-15 10:25:30 WARNING Memory usage high: 85% 2024-01-15 10:26:15 ERROR Failed to connect database 2024-01-15 10:26:20 ERROR Connection timeout 2024-01-15 10:28:30 WARNING Slow query detected 2024-01-15 10:30:00 ERROR Null pointer exception egrep with {n} (date pattern) 2024-01-15 10:23:45 INFO Application started 2024-01-15 10:24:01 DEBUG Loading configuration 2024-01-15 10:24:02 INFO Configuration loaded successfully Extract IP addresses 192.168.1.100 Extract timestamps 2024-01-15 10:23:45 2024-01-15 10:24:01 2024-01-15 10:24:02 2024-01-15 10:25:30 2024-01-15 10:26:15BRE vs ERE 对比功能grep (BRE)egrep (ERE)或运算|1次或多次\0次或1次\??分组\(\)()重复次数\{n,m\}{n,m}解析egrep语法更简洁不需要转义|、、?、()、{}。现代grep推荐使用grep -E代替egrep两者完全等价。提取IP地址和时间戳是正则表达式的经典应用场景。六、实战场景应用6.1 日志分析# 统计各类错误出现次数grepERROR/tmp/shell_test/app.log|egrep-oERROR.*|sort|uniq-c|sort-rn# 提取错误发生的时间线grepERROR/tmp/shell_test/app.log|awk{print $1, $2, $3}# 提取所有错误消息内容grepERROR/tmp/shell_test/app.log|cut-d -f4-实际输出 Error count by type 1 ERROR Null pointer exception 1 ERROR Failed to connect database 1 ERROR Connection timeout Timeline of errors 2024-01-15 10:26:15 ERROR 2024-01-15 10:26:20 ERROR 2024-01-15 10:30:00 ERROR All error messages Failed to connect database Connection timeout Null pointer exception解析sort | uniq -c | sort -rn是统计重复行出现次数的经典管道组合——先排序再去重计数最后按数量降序排列。这在日志分析中极为常用。6.2 配置文件搜索# 查找所有非注释、非空行的配置项grep-v^#/tmp/shell_test/config.conf|grep-v^$# 查找数据库相关配置grepdatabase/tmp/shell_test/config.conf# 提取所有键值对grep/tmp/shell_test/config.conf|grep-v^#实际输出 Non-comment settings server_port8080 server_hostlocalhost max_connections100 timeout30 debug_modetrue log_levelINFO database_host192.168.1.100 database_port3306 database_namemyapp Database settings database_host192.168.1.100 database_port3306 database_namemyapp解析grep -v ^#过滤注释行grep -v ^$过滤空行两者组合可以提取纯配置内容。这在解析Nginx、MySQL等配置文件时非常实用。6.3 多文件搜索与进程查找# 递归搜索多个文件只搜.txt文件grep-rnHello/tmp/shell_test/--include*.txt# 查找运行中的进程排除grep自身psaux|grepbash|grep-vgrep# 从文件读取搜索模式echoERRORpatterns.txtechoWARNINGpatterns.txtgrep-fpatterns.txt /tmp/shell_test/app.log# 排除多个模式grep-v-eDEBUG-eINFO/tmp/shell_test/app.log实际输出 Search in multiple files /tmp/shell_test/sample.txt:1:Hello World /tmp/shell_test/sample.txt:4:Hello Shell /tmp/shell_test/extract_test/sample.txt:1:Hello World /tmp/shell_test/extract_test/sample.txt:4:Hello Shell Find processes root 4819 0.0 0.0 7604 2808 ? S 23:21 0:00 /bin/bash /etc/init.d/HSSInstall start Pattern from file 2024-01-15 10:25:30 WARNING Memory usage high: 85% 2024-01-15 10:26:15 ERROR Failed to connect database 2024-01-15 10:26:20 ERROR Connection timeout 2024-01-15 10:28:30 WARNING Slow query detected 2024-01-15 10:30:00 ERROR Null pointer exception Exclude multiple patterns 2024-01-15 10:25:30 WARNING Memory usage high: 85% 2024-01-15 10:26:15 ERROR Failed to connect database 2024-01-15 10:26:20 ERROR Connection timeout 2024-01-15 10:28:30 WARNING Slow query detected 2024-01-15 10:30:00 ERROR Null pointer exception解析--include限制搜索文件类型--exclude排除特定文件grep -v grep是查找进程时的经典技巧——ps aux | grep xxx本身会匹配到grep进程用-v grep排除grep -f file从文件读取多个搜索模式适合批量匹配-e可以指定多个搜索模式-v -e组合实现排除多个模式总结本文系统讲解了Shell脚本中两大核心工具集——文件查找与文本搜索核心知识点回顾find命令基本查找-name按名称、-type按类型、-iname忽略大小写条件查找-size按大小、-mtime/-mmin按时间、-perm按权限、-user按用户结果处理-exec {} \;逐个执行、-exec {} 批量执行、xargs管道组合安全实践-print0xargs -0处理含空格文件名文件压缩tar-czvfgzip压缩最常用、-cjvfbzip2压缩、-cJvfxz压缩gzip/bzip2单文件压缩zcat/zgrep直接操作压缩文件压缩比xz bzip2 gzip速度则相反grep/egrep常用选项-n行号、-c计数、-v反向、-i忽略大小写、-r递归、-o仅匹配部分上下文-A后文、-B前文、-C上下文日志排错利器正则表达式^/$锚定、.任意字符、[]字符类、*重复扩展正则egrep/grep -E支持|、、?、()、{n,m}无需转义实战技巧sort | uniq -c统计、grep -f多模式、--include限定文件类型系列完结。通过四篇文章我们从Shell基础命令出发逐步深入变量与条件测试、高级变量与函数编程、工具命令与文本搜索构建了完整的Shell脚本编程知识体系。思考题find -exec {} \;和find -exec {} 有什么区别哪种方式性能更好为什么如何用find命令查找7天内修改过的所有.conf配置文件并备份到指定目录locate和find各有什么优缺点在什么场景下应该选择哪个tar -czvf和tar -cjvf分别使用什么压缩算法如何选择grep -v INFO和grep -v -e INFO -e DEBUG有什么区别如何用egrep提取日志文件中所有的IP地址和URLgrep -A 2 -B 2 ERROR app.log的输出是什么含义在日志分析中有什么用编写一个Shell脚本使用find查找大于100MB的日志文件用gzip压缩后移动到归档目录并输出压缩前后的大小对比。ps aux | grep nginx | grep -v grep中为什么要加grep -v grep有没有更优雅的替代方案如何使用grep统计Nginx访问日志中各HTTP状态码的出现次数并按频率排序