强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 8 章:核心工具

第 8 章:核心工具

8.1 文件查找:find

8.1.1 基本用法

# 按名称查找
$ find /etc -name "*.conf"
/etc/resolv.conf
/etc/hostname
/etc/inittab

# 按类型查找
$ find /tmp -type f         # 普通文件
$ find /tmp -type d         # 目录
$ find /tmp -type l         # 符号链接

# 按大小查找
$ find /var -size +1M       # 大于 1MB
$ find /tmp -size 0         # 空文件

# 按时间查找
$ find /tmp -mtime -1       # 最近 1 天修改
$ find /etc -mtime +30      # 超过 30 天修改
$ find /var -newer /tmp/old  # 比 old 文件更新

# 按权限查找
$ find /usr -perm 755       # 精确权限
$ find /usr -perm -644      # 至少包含 644

8.1.2 执行操作

# 删除文件
$ find /tmp -name "*.log" -delete

# 执行命令
$ find /tmp -name "*.txt" -exec ls -l {} \;

# 使用 xargs
$ find /tmp -name "*.log" | xargs rm -f

# 批量处理
$ find /etc -name "*.conf" -exec grep "dns" {} +

8.1.3 实用示例

# 查找大文件
$ find / -type f -size +10M 2>/dev/null -exec ls -lh {} \;

# 查找并清理日志
$ find /var/log -name "*.log" -mtime +7 -delete

# 查找可执行文件
$ find /usr/bin -type f -executable -name "busy*"

# 查找符号链接
$ find / -type l -name "sh" -exec ls -la {} \;

# 查找空目录
$ find /tmp -type d -empty -delete

8.2 文本搜索:grep

8.2.1 基本用法

# 搜索字符串
$ grep "root" /etc/passwd
root:x:0:0:root:/root:/bin/sh

# 忽略大小写
$ grep -i "Root" /etc/passwd

# 递归搜索目录
$ grep -r "nameserver" /etc/

# 显示行号
$ grep -n "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/sh

# 反向匹配
$ grep -v "nobody" /etc/passwd

# 只显示匹配部分
$ grep -o "root" /etc/passwd | wc -l

8.2.2 正则表达式

# 基本正则
$ grep "^root" /etc/passwd          # 以 root 开头
$ grep "sh$" /etc/passwd            # 以 sh 结尾
$ grep "r..t" /etc/passwd           # 匹配 r 开 t 结中间两个字符

# 扩展正则(-E 或 egrep)
$ grep -E "root|nobody" /etc/passwd
$ grep -E "[0-9]+" /etc/passwd
$ egrep "(root|admin)" /etc/passwd

# 注意:BusyBox grep 不支持 -P(PCRE)
# 错误:grep -P '\d+' file
# 正确:grep -E '[0-9]+' file

8.2.3 常用选项

# 统计匹配行数
$ grep -c "error" /var/log/messages

# 显示匹配文件名
$ grep -l "nameserver" /etc/*

# 显示不匹配的文件名
$ grep -L "nameserver" /etc/*

# 上下文显示
$ grep -A 3 "error" logfile      # 匹配行后 3 行
$ grep -B 3 "error" logfile      # 匹配行前 3 行
$ grep -C 3 "error" logfile      # 匹配行前后各 3 行

# 静默模式(只看退出码)
$ grep -q "root" /etc/passwd && echo "Found"

8.3 流编辑器:sed

8.3.1 基本替换

# 替换第一个匹配
$ echo "hello world" | sed 's/world/busybox/'
hello busybox

# 全局替换
$ echo "aaa" | sed 's/a/b/g'
bbb

# 忽略大小写
$ echo "Hello" | sed 's/hello/hi/I'
hi

# 写入文件(原地编辑)
$ sed -i 's/old/new/g' file.txt

# 原地编辑(创建备份)
$ sed -i.bak 's/old/new/g' file.txt

8.3.2 删除和插入

# 删除行
$ sed '3d' file.txt            # 删除第 3 行
$ sed '2,5d' file.txt          # 删除 2-5 行
$ sed '/^#/d' file.txt         # 删除注释行
$ sed '/^$/d' file.txt         # 删除空行

# 插入行
$ sed '1i\New first line' file.txt
$ sed '$a\New last line' file.txt

# 替换行
$ sed '3c\New line 3' file.txt

8.3.3 高级用法

# 多命令
$ sed -e 's/foo/bar/' -e 's/baz/qux/' file.txt

# 地址范围
$ sed '10,20s/old/new/g' file.txt   # 只在 10-20 行替换

# 条件执行
$ sed '/pattern/s/old/new/g' file.txt

# 提取行
$ sed -n '10,20p' file.txt          # 打印 10-20 行

# 引用匹配
$ echo "hello" | sed 's/\(hel\)lo/\1p/'
helpp

# 变量替换
$ NEW="world"
$ sed "s/hello/$NEW/" file.txt

8.3.4 配置文件编辑示例

# 修改配置文件
$ sed -i 's/^#DNS=.*/DNS=8.8.8.8/' /etc/systemd/resolved.conf

# 在行前添加
$ sed -i '/^\[mysqld\]/a\max_connections=100' /etc/my.cnf

# 删除配置项
$ sed -i '/^old_setting/d' /etc/config.conf

# 取消注释
$ sed -i 's/^#\(option\)/\1/' config.txt

8.4 文本处理:awk

8.4.1 基本用法

# 打印特定字段
$ echo "hello world" | awk '{print $1}'
hello

$ cat /etc/passwd | awk -F: '{print $1, $3}'
root 0
nobody 65534

# 打印所有字段
$ echo "a b c" | awk '{print $0}'
a b c
$ echo "a b c" | awk '{print NR, NF}'
1 3

8.4.2 模式匹配

# 匹配模式
$ awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/sh

# 条件过滤
$ awk -F: '$3 == 0 {print $1}' /etc/passwd
root

# 大小比较
$ awk -F: '$3 >= 1000 {print $1}' /etc/passwd

8.4.3 字段分隔

# 指定分隔符
$ awk -F: '{print $1}' /etc/passwd

# 多分隔符
$ echo "a:b-c" | awk -F '[:\-]' '{print $1, $2, $3}'
a b c

# 输出分隔符
$ awk -F: -v OFS=',' '{print $1, $3}' /etc/passwd
root,0

8.4.4 变量和计算

# 内置变量
# NR - 当前行号
# NF - 当前行字段数
# FS - 输入分隔符
# OFS - 输出分隔符

# 求和
$ echo -e "1\n2\n3" | awk '{sum+=$1} END {print sum}'
6

# 统计行数
$ awk 'END {print NR}' /etc/passwd

# 最大值
$ echo -e "3\n1\n4\n1\n5" | awk 'max < $1 {max=$1} END {print max}'
5

8.4.5 实用脚本

# 格式化磁盘使用
$ df -h | awk 'NR>1 {printf "%-20s %s\n", $5, $6}'

# 统计日志中的错误
$ awk '/error/i {count++} END {print "Errors:", count}' /var/log/messages

# 提取 IP 地址
$ awk '/inet / {print $2}' /proc/net/tcp

# 处理 CSV
$ awk -F, '{print $2}' data.csv

# 条件求和
$ awk '$1 > 100 {sum+=$2} END {print sum}' data.txt

8.5 归档工具:tar

8.5.1 基本操作

# 创建归档
$ tar cf archive.tar /tmp/files/

# 创建 gzip 压缩归档
$ tar czf archive.tar.gz /tmp/files/

# 创建 bzip2 压缩归档
$ tar cjf archive.tar.bz2 /tmp/files/

# 创建 xz 压缩归档
$ tar cJf archive.tar.xz /tmp/files/

# 解压归档
$ tar xf archive.tar
$ tar xzf archive.tar.gz
$ tar xjf archive.tar.bz2
$ tar xJf archive.tar.xz

# 解压到指定目录
$ tar xzf archive.tar.gz -C /tmp/extract/

8.5.2 高级用法

# 查看归档内容
$ tar tzf archive.tar.gz

# 排除文件
$ tar czf backup.tar.gz --exclude='*.log' /var/

# 使用排除列表
$ cat exclude.txt
*.log
*.tmp
cache/

$ tar czf backup.tar.gz -X exclude.txt /var/

# 增量备份
$ tar czf backup-full.tar.gz -g /tmp/snapshot /var/
$ tar czf backup-incr.tar.gz -g /tmp/snapshot /var/

# 保留权限和符号链接
$ tar czpf backup.tar.gz --same-owner /etc/

8.5.3 cpio(initramfs)

# 创建 cpio 归档(initramfs 必用)
$ cd rootfs
$ find . | cpio -o -H newc | gzip > ../initramfs.cpio.gz

# 解压 cpio
$ mkdir extract && cd extract
$ zcat ../initramfs.cpio.gz | cpio -idmv

# BusyBox cpio 支持的格式
# newc - 新 ASCII 格式(initramfs 标准)
# odc  - POSIX.1 兼容格式

8.6 压缩工具

8.6.1 gzip / gunzip

# 压缩文件
$ gzip file.txt                  # 产生 file.txt.gz,删除原文件
$ gzip -k file.txt               # 保留原文件
$ gzip -9 file.txt               # 最高压缩率

# 解压
$ gunzip file.txt.gz

# 查看压缩文件
$ zcat file.txt.gz               # 不解压直接查看
$ zless file.txt.gz              # 分页查看
$ zgrep "pattern" file.txt.gz    # 搜索压缩文件

8.6.2 bzip2 / bunzip2

# 压缩
$ bzip2 file.txt
$ bzip2 -k file.txt              # 保留原文件
$ bzip2 -9 file.txt              # 最高压缩率

# 解压
$ bunzip2 file.txt.bz2

# 查看
$ bzcat file.txt.bz2

8.6.3 xz / unxz

# 压缩(压缩率最高)
$ xz file.txt
$ xz -k file.txt
$ xz -9 file.txt                 # 最高压缩率

# 解压
$ unxz file.txt.xz

# 查看
$ xzcat file.txt.xz

8.6.4 压缩工具对比

工具压缩率速度扩展名
gzip.gz
bzip2较慢.bz2
xz.xz
lz4极快.lz4
zstd.zst

8.7 文本处理工具集

8.7.1 cut — 字段提取

# 按分隔符提取字段
$ cut -d: -f1 /etc/passwd       # 提取第 1 字段
$ cut -d: -f1,3 /etc/passwd     # 提取第 1 和第 3 字段

# 按字符位置提取
$ cut -c1-5 file.txt            # 提取前 5 个字符

# 按字节提取
$ cut -b1-10 file.txt

8.7.2 sort — 排序

# 字母排序
$ sort file.txt

# 数值排序
$ sort -n numbers.txt

# 反向排序
$ sort -r file.txt

# 去重
$ sort -u file.txt

# 按字段排序
$ sort -t: -k3 -n /etc/passwd

# 忽略大小写
$ sort -f file.txt

8.7.3 uniq — 去重

# 去除相邻重复行(通常配合 sort 使用)
$ sort file.txt | uniq

# 统计重复次数
$ sort file.txt | uniq -c

# 只显示重复行
$ sort file.txt | uniq -d

# 只显示唯一行
$ sort file.txt | uniq -u

8.7.4 tr — 字符转换

# 大小写转换
$ echo "hello" | tr 'a-z' 'A-Z'
HELLO

# 删除字符
$ echo "hello 123" | tr -d '0-9'
hello 

# 压缩空格
$ echo "hello   world" | tr -s ' '
hello world

# 替换字符
$ echo "hello" | tr 'l' 'r'
herro

8.7.5 wc — 统计

# 统计行数
$ wc -l /etc/passwd

# 统计字数
$ wc -w file.txt

# 统计字节数
$ wc -c file.txt

# 综合统计
$ wc file.txt
  10  20  100 file.txt

8.7.6 diff — 比较文件

# 比较两个文件
$ diff file1.txt file2.txt

# 并排显示
$ diff -y file1.txt file2.txt

# 统一格式
$ diff -u file1.txt file2.txt

# 比较目录
$ diff -r dir1/ dir2/

8.7.7 head / tail — 首尾显示

# 显示前 N 行
$ head -20 /etc/passwd

# 显示后 N 行
$ tail -20 /var/log/messages

# 实时跟踪文件
$ tail -f /var/log/messages

# 显示从第 N 行开始
$ tail -n +10 /etc/passwd

8.8 其他工具

8.8.1 dd — 数据复制

# 创建文件
$ dd if=/dev/zero of=file bs=1M count=10

# 备份磁盘
$ dd if=/dev/sda of=/tmp/disk.img bs=4M

# 写入镜像
$ dd if=rootfs.img of=/dev/sdb bs=4M

# 显示进度
$ dd if=/dev/zero of=file bs=1M count=100 status=progress

8.8.2 xargs — 参数传递

# 基本用法
$ find /tmp -name "*.log" | xargs rm

# 处理空格
$ find /tmp -name "*.log" -print0 | xargs -0 rm

# 限制每次参数数量
$ cat list.txt | xargs -n 5 echo

# 使用占位符
$ find /tmp -name "*.txt" | xargs -I {} cp {} /backup/

8.9 本章小结

工具用途关键选项
find文件查找-name, -type, -exec
grep文本搜索-i, -r, -E, -v
sed流编辑s/old/new/g, -i, -e
awk文本处理-F, {print}, END
tar归档czf, xzf, -C
cut字段提取-d, -f, -c
sort排序-n, -r, -u
tr字符转换a-z:A-Z, -d, -s

扩展阅读


上一章: 第 7 章 — ash Shell
下一章: 第 9 章 — 系统工具