← 全部笔记/我的笔记 2026-10-21 · 约 9 分钟

文件管理进阶:查找 · 下载 · 重定向 · 打包

更新于 2026-10-21 · 约 3591 字 · 阅读 9 分钟

打开练习题(折叠答案)→
本文目录

一句话总结:find 找、wget/curl 拿、重定向分流、tar 打包、split 切片——这五件事覆盖了运维日常 80% 的文件操作。 适用:Rocky Linux / CentOS 9(GNU 工具)。练习目录统一用 /tmp/adv。

一、find:按条件找文件

find 会递归遍历目录,默认把找到的路径打印出来。语法:

find 起始目录 [条件...] [动作]

1.1 按名字

选项 说明 示例
-name 按文件名匹配,区分大小写,支持通配符 find /etc -name "ifcfg-ens33"
-iname 忽略大小写 find /etc -iname "*.LOG"
-path 按完整路径匹配 find / -path "*/nginx/*.conf"
-regex 用正则匹配整个路径 find . -regex ".*\.\(jpg\|png\)"
find /etc -name "ifcfg-*"      # 前缀匹配
find /etc -name "*cfg*"        # 包含匹配
find /etc -name "*.conf" -type f

通配符要加引号,否则会被 shell 先展开。

1.2 按大小

写法 含义
-size +3M 大于 3M
-size 3M 等于 3M(按单位取整后比较)
-size -3M 小于 3M
单位 c 字节、k KB、M MB、G GB
find /etc -size +3M
find /var/log -size +100M -name "*.log"
find /tmp -size 0            # 空文件
find /tmp -empty             # 空文件或空目录

1.3 按时间

选项 含义 例子
-mtime +3 修改时间 3 天以前(超过 3×24 小时) 找老文件清理
-mtime 3 修改时间在 3~4 天 之间
-mtime -3 修改时间 3 天以内 找最近改过的
-mmin -30 30 分钟以内 排查刚改的配置
-atime / -ctime 访问时间 / 状态变化时间 同上规则
-newer file 比 file 更新的文件 增量备份
find /etc -mtime +3
find /var/log -mtime +7 -name "*.log"
find /tmp -mmin -10
find /data -newer /data/last_backup.tar.gz

1.4 按类型、属主、权限

选项 说明 示例
-type f 普通文件 find /etc -type f
-type d 目录 find / -type d -name "test"
-type l 符号链接 find /usr/bin -type l
-user / -group 属主 / 属组 find /home -user zhangsan
-perm 644 权限正好是 644 find / -perm 777
-perm -u+x 至少属主可执行 找可疑脚本
-nouser / -nogroup 属主/属组已不存在的孤儿文件 清理离职用户文件

1.5 控制深度

选项 说明
-maxdepth N 最多向下 N 层(必须写在其他条件前)
-mindepth N 从第 N 层开始
find /etc -maxdepth 2 -name "*.conf"      # 只看两层以内
find / -maxdepth 1 -type d                # 只看根下一级目录

1.6 逻辑组合:-a、-o、!

运算符 含义 说明
-a 并且(默认) 可省略
-o 或者 优先级低于 -a,建议加括号
! 取反 ! -name "*.log"
find /etc -size +3M -o -name "*.log"        # 大于3M 或 以.log结尾
find /etc -type f -a -size +3M              # 普通文件 且 大于3M
find /etc -type f ! -name "*.conf"          # 排除 .conf
find / \( -name "*.log" -o -name "*.tmp" \) -size +10M

\( \) 要给 shell 转义,否则会被当成子 shell。

1.7 找到之后做动作

动作 说明 示例
默认 打印路径 find /etc -name "*.log"
-print0 用 \0 分隔输出,配合 xargs -0 处理带空格的文件名 见下方示例
-exec cmd {} \; 对每个结果执行一次命令 find /tmp -name "*.log" -exec rm -f {} \;
-exec cmd {} + 把所有结果拼成一次命令,效率更高 find /tmp -name "*.log" -exec rm -f {} +
-delete 直接删除(隐含 -depth) find /tmp -name "*.log" -delete
-ls 用 ls -l 格式列出 find /etc -name "*.conf" -ls
find /etc -type f -name "*.log" -size +3M -exec rm -rf {} \;
find /etc -size -3M -exec cp -a {} /test/ \;
find /aaa -size -3M -exec mv {} /test/ \;
find /log -size +10M -exec rm -rf {} \;

# 文件名带空格时,用 -print0 配合 xargs -0 最安全
find . -name "*.log" -print0 | xargs -0 rm -f
# 多个结果拼成一条命令,比 \; 快
find /tmp -name "*.tmp" -exec rm -f {} +

cp -a = 拷贝内容 + 元数据(权限、属主、时间戳),做备份优先用它。 {}\; 里的 {} 代表当前找到的文件,\; 是 -exec 的结束符,分号要转义。

先确认再删除是最稳的习惯:

find /tmp -mtime +7 -name "*.log" -print      # 先看
find /tmp -mtime +7 -name "*.log" -delete     # 再删

二、下载与上传:wget / curl / rz / sz

2.1 wget

选项 作用 示例
-O 文件 另存为指定文件名 wget -O /tmp/nginx.tar.gz http://...
-P 目录 保存到指定目录(保留原文件名) wget -P /tmp https://...
-c 断点续传 大文件下载中断后重来
-q 安静模式,不输出进度 脚本里用
-b 后台下载 wget -b URL
--no-check-certificate 跳过 HTTPS 证书校验 自签证书站点
--limit-rate=200k 限速 避免占满带宽
-r -np 递归下载、不追上级目录 镜像站点
-i 文件 从文件读 URL 列表 批量下载
--spider 只检测链接是否存在 巡检
-T 秒 超时时间
yum install wget -y

# 默认保存为原文件名
wget http://nginx.org/download/nginx-1.22.1.tar.gz

# 另存为 / 指定目录
wget -O /tmp/1.tar.gz http://nginx.org/download/nginx-1.22.1.tar.gz
wget -P /tmp http://nginx.org/download/nginx-1.22.1.tar.gz

遇到 SSL 报错(证书过期、自签、域名不匹配)两种处理:

wget --no-check-certificate https://nginx.org/download/nginx-1.22.1.tar.gz
wget http://nginx.org/download/nginx-1.22.1.tar.gz   # 改走 http

2.2 curl

选项 作用 示例
-o 文件 保存到指定文件 curl -o /tmp/1.png URL
-O 用远端文件名保存 curl -O http://x/a.tar.gz
-L 跟随 301/302 跳转 短链接必备
-k 跳过证书校验(insecure) 自签证书
-s 静默;-S 出错时才显示 脚本里常用 -sS
-I 只看响应头(HEAD) 测站点是否存活
-X 方法 指定请求方法 -X POST、-X DELETE
-d 数据 发送表单/JSON 数据 -d 'a=1&b=2'
-H 头 自定义请求头 -H "Content-Type: application/json"
-u 用户:密码 Basic 认证
-T 文件 上传文件(PUT)
-w 格式 输出统计信息 -w "%{http_code} %{time_total}\n"
--retry N 失败重试 N 次
curl -o /tmp/1.png http://www.example.com/1.png
curl -k -o /tmp/1.png https://www.example.com/1.png   # 跳过证书
curl -I https://www.baidu.com                          # 只看响应头
curl -s http://127.0.0.1:8080/health                   # 静默探活

curl 的进阶玩法:下载脚本并立即执行

# 服务端准备
apt-get install nginx -y        # CentOS 用 yum install nginx -y
cd /var/www/html && mkdir test
vi test/a.sh                    # 写几行命令
systemctl start nginx

# 客户端一条命令下载并执行
curl -s http://192.168.71.8/test/a.sh | bash

⚠️ 这条命令会把远处脚本直接交给 bash 执行,等于把机器交给对方。生产环境务必先 curl -o a.sh 下载,cat 检查内容再执行;内网可信源也建议核对校验和。

2.3 rz / sz:终端里传文件

yum install lrzsz -y

rz          # 上传:从本机选文件传到服务器
rz -y       # 覆盖已存在的同名文件
sz file     # 下载:把服务器文件拉到本机
sz a.txt b.txt

rz/sz 走 ZMODEM 协议,需要终端软件支持(Xshell、SecureCRT、MobaXterm、iTerm2 + trigger)。纯 ssh 命令行本身不支持;大文件建议用 scp/sftp: scp file user@host:/path/、scp user@host:/path/file .

三、文件描述符与输入输出重定向

3.1 什么是文件描述符

进程每打开一个文件,操作系统都会分配一个非负整数编号,这个编号叫文件描述符(file descriptor,也叫文件句柄)。

进程(打开文件) ──> 文件描述符 ──> 操作系统内核 ──> 硬盘

程序与进程“交互”无非是输入 + 输出;Linux 一切皆文件,所以:

  • 输入操作 → 某个打开的文件 → 某个文件描述符
  • 输出操作 → 某个打开的文件 → 某个文件描述符

文件描述符原理

图:进程通过文件描述符与内核、磁盘打交道

3.2 三个标准文件描述符

编号 名称 默认设备 说明
0 标准输入 stdin 键盘 程序从这读数据
1 标准输出 stdout 屏幕 正常结果写这里
2 标准错误 stderr 屏幕 报错信息写这里
ls /etc/passwd /etc/nofile      # 第二个路径不存在,会走 stderr

3.3 重定向符号

写法 作用 例子
> 标准输出覆盖写入 ip a 1> /tmp/a.txt
>> 标准输出追加 echo x >> /tmp/a.txt
2> 标准错误重定向 asdfasdf 2> /tmp/err.txt
2>> 标准错误追加
&> 正确 + 错误一起重定向 cmd &> /tmp/all.txt
2>&1 把 stderr 指向 stdout 当前的位置 cmd > /tmp/all.txt 2>&1
1>&2 把 stdout 指向 stderr 脚本里输出错误信息
< 标准输入重定向 wc -l < /etc/passwd
<< here-doc,多行输入 见 3.4
<<< here-string,单行输入 cat <<< "hello"
管道 前一个命令的 stdout 作为后一个的 stdin 见下方示例
tee 同时输出到屏幕和文件 见下方示例

顺序很重要:> file 2>&1 和 2>&1 > file 结果完全不同。

ps aux | grep nginx          # 管道:前一个的输出给后一个
cmd | tee -a /tmp/log.txt    # 同时打印到屏幕并追加到文件

cmd > /tmp/all.txt 2>&1    # 正确:先指向文件,再让 2 指向 1 的位置 → 都进文件
cmd 2>&1 > /tmp/all.txt    # 错误:2 先指向屏幕,1 再指向文件 → 错误还是打在屏幕

3.4 丢弃输出与 here-doc

cmd 1> /dev/null 2> /dev/null    # 正确错误都丢弃
cmd &> /dev/null                  # & 代表 1 和 2
cmd > /dev/null 2>&1              # 等价写法

/dev/null 是“黑洞设备”,写进去的东西直接消失;/dev/zero 读出来全是 0,/dev/urandom 是随机数。

here-doc:把一段多行文本当作标准输入,常用于脚本里写入配置文件。

cat > /tmp/xxx.txt << "EOF"
11111111111
echo $PATH
EOF
  • << "EOF":引号会关闭变量替换,上面会原样写入 echo $PATH;
  • << EOF(不加引号):$PATH 会被展开成实际路径;
  • <<- EOF:允许用 Tab 缩进结束符(不能是空格)。

四、sort / uniq / cut / wc:文本统计四件套

4.1 sort 排序

选项 作用 示例
-n 按数字大小排序 sort -n nums.txt
-r 倒序 sort -nr nums.txt
-k 2 按第 2 列排序 sort -k2 file
-t : 指定字段分隔符 sort -t: -k3 -n /etc/passwd
-u 排序并去重
-h 按人类可读大小(1K/2M/3G) 常配合 du -sh 排序
-f 忽略大小写
-V 按版本号排序 sort -V
-o 文件 结果写回文件 不能直接 sort f > f
sort -t: -k3 -n /etc/passwd | head -5        # 按 UID 数字排序取前5
du -sh /var/log/* | sort -rh | head -5       # 目录占用 Top5

提醒:sort f > f 会先把文件清空再读,结果为空;要写回用 sort -o f f。

4.2 uniq 去重

uniq 只能去掉相邻的重复行,所以必须先 sort。

选项 作用
-c 统计每行出现次数
-d 只显示重复的行
-u 只显示不重复的行
-i 忽略大小写
sort file.txt | uniq -c | sort -rn        # 统计词频,按次数倒序
sort file.txt | uniq -d                   # 只看重复项

经典:访问日志 Top 10 IP

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

流程:取第一列 → 排序让相同 IP 相邻 → 计数 → 按次数倒序 → 取前 10。

4.3 cut 按列截取

选项 作用 示例
-d ':' 指定分隔符 cut -d: -f1 /etc/passwd
-f 1,3 取第 1、3 列,-f 1-3 取范围 cut -d: -f1,3 /etc/passwd
-c 1-10 按字符位置截取 cut -c1-10 file
-s 不含分隔符的行不输出
--complement 取反,保留其余列
--output-delimiter 输出时换分隔符 cut -d: -f1,3 --output-delimiter=' '
cut -d: -f1 /etc/passwd | head
cut -d: -f1,7 /etc/passwd

4.4 wc 统计

选项 统计什么
-l 行数
-w 单词数
-c 字节数
-m 字符数(中文按字符算)
wc -l /etc/passwd
grep -c bash /etc/passwd        # 等价于统计匹配行数

五、打包与压缩:tar / zip

打包是把多个文件放到一起得到一个文件;压缩是对空间做缩减。Linux 上通常一步完成。

5.1 tar 参数表

选项 作用
-c 创建归档(create)
-x 解包(extract)
-t 列出内容,不解压
-f 文件 指定归档文件名(必须紧挨着文件名)
-v 显示过程
-z gzip 压缩(.tar.gz)
-j bzip2 压缩(.tar.bz2,压缩率高、慢)
-J xz 压缩(.tar.xz,压缩率最高、最慢)
-C 目录 解压到指定目录
-p 保留权限
-P 允许绝对路径
--exclude=模式 排除文件
-r / -u 追加 / 更新归档
--remove-files 打包后删除源文件(慎用)
tar -cvzf a.tar.gz /data          # gzip 压缩
tar -cvjf a.tar.bz2 /data         # bzip2(yum install bzip2 -y)
tar -cvJf a.tar.xz /data          # xz

tar -tzf a.tar.gz                 # 只看内容
tar -xzf a.tar.gz                 # 解压到当前目录
tar -xzf a.tar.gz -C /data/       # 解压到指定目录
tar -xvf a.tar.bz2 -C /data/      # 解压时不用指定算法,tar 会自动识别

新写法可以省略开头的 -:tar czf a.tar.gz /data 等价。

5.2 让压缩包里“不带”被压缩目录本身

默认 tar -czf a.tar.gz /data 解压出来会带 data/ 这一层。如果只想要里面的内容:

cd /data
tar -cvzf ../a.tar.gz ./*      # 用相对路径打包,解压后没有 data 目录

按日期命名备份包:

tar -cvzf `date '+%Y_%m_%d_%H_%M_%S'`.tar.gz /data
# 结果形如 2026_10_20_21_30_00.tar.gz

5.3 zip / unzip

zip 是跨平台通用格式(Windows 直接能打开)。

命令 选项 作用
zip -r 递归打包目录
zip -q 安静模式
zip -9 最高压缩比(1~9)
zip -e 设置密码
zip -x 模式 排除文件
unzip -l 列出内容
unzip -d 目录 解压到指定目录
unzip -o 覆盖已有文件不询问
unzip -O GBK 解决 Windows 中文 zip 乱码
yum install zip unzip -y

zip -q aaa.zip /data/1.txt /data/2.txt /data/3.png
zip -rq bbb.zip /data/
unzip -l bbb.zip
unzip bbb.zip -d /nnn

六、大文件切分与合并

超大文件(日志、备份包)不方便传输时,可以先切片,到对端再合并。

tar czf a.tar.gz /etc/

# 按大小切:每片 2M,默认后缀 xaa、xab、xac…
split -b 2M a.tar.gz

# 按行切:每 1000 行一片;-d 用数字后缀,-a 3 后缀长度 3
split -l 1000 access.log part_

# 合并(按文件名顺序)
cat xa* > b.tar.gz

# 校验:两个文件 md5 一致说明内容完全相同
md5sum a.tar.gz b.tar.gz
split 选项 作用
-b 大小 按字节切,支持 K/M/G
-l 行数 按行数切
-d 后缀用数字(00、01…)
-a N 后缀长度
--verbose 显示切片过程

合并时 cat xa* 依赖文件名排序:默认 xaa xab ... 正好有序;用 -d 数字后缀也天然有序。自定义前缀时要写成 cat part_*,并确认顺序。

md5sum 还能批量校验:

md5sum *.tar.gz > checksums.md5
md5sum -c checksums.md5

安全性要求高时用 sha256sum,原理相同,碰撞概率更低。

七、扩展:inode、文件系统与软硬链接

这部分是「文件管理高级」的底层原理,理解了再看 find、tar、df 会顺很多。

7.1 inode 是什么

文件在磁盘上分两部分存:

部分 存什么
inode(索引节点) 元数据:权限、属主、大小、时间戳、数据块指针、链接数
数据块(block) 文件真正的内容
文件名不在 inode 里,目录才是“文件名 → inode 号”的映射表。
stat /etc/passwd          # 看 inode 号、块数、三个时间
ls -i /etc/passwd         # 只看 inode 号
df -i                     # 看各分区 inode 使用率

文件系统底层核心原理

图:文件系统、inode 与数据块的关系

常见故障:df -h 显示还有空间,但写入报 No space left on device——多半是 inode 用完了(大量小文件),用 df -i 确认。

7.2 一个分区一个文件系统

分区格式化后才有文件系统(ext4/xfs),挂载到某个目录才能访问。

一个分区一个文件系统

图:分区、文件系统与挂载点的关系

lsblk -f            # 看分区、文件系统类型、挂载点
df -hT              # 看已挂载文件系统
mount | column -t

7.3 硬链接与软链接(复习)

对比 硬链接 软链接
本质 同一 inode 的多个名字 独立文件,内容是目标路径
跨分区 不行 可以
链接目录 不行 可以
删除源文件 数据还在,链接数 -1 链接失效

硬连接与软连接原理

图:硬链接共享 inode,软链接指向路径

ln /data/a.txt /data/b.txt        # 硬链接
ln -s /data/a.txt /data/c.txt     # 软链接
ls -li /data/                     # 看 inode 号是否相同

速查表

# find
find /etc -name "*.conf" -type f -size +3M
find /var/log -mtime +7 -name "*.log" -delete
find / -maxdepth 2 -type d -name "test"
find /data -size +1G -exec ls -lh {} \;
find . -name "*.log" -print0 | xargs -0 rm -f

# 下载
wget -O /tmp/a.tar.gz http://x/a.tar.gz
wget -c --no-check-certificate https://x/a.tar.gz
curl -k -L -o /tmp/a.png https://x/a.png
curl -s http://x/a.sh | bash        # 危险,先看内容
rz; sz file

# 重定向
cmd > out 2>&1
cmd &> /dev/null
cmd 2>/tmp/err
cat > /tmp/f << "EOF"
...
EOF

# 统计
sort -t: -k3 -n /etc/passwd
sort f | uniq -c | sort -rn | head
cut -d: -f1,7 /etc/passwd
wc -l file

# 打包
tar -czf a.tar.gz dir/
tar -xzf a.tar.gz -C /data/
tar -tzf a.tar.gz
zip -rq a.zip dir/; unzip a.zip -d out/

# 切片
split -b 2M big.tar.gz
cat xa* > big2.tar.gz
md5sum big*.tar.gz

常见坑

  1. find -name 的通配符要用引号,否则 shell 先展开。
  2. -maxdepth 必须放在其他条件前面,否则 GNU find 会警告或行为异常。
  3. -exec ... \; 的分号要转义,{} 代表当前文件;能用 + 就别用 \;。
  4. -mtime +3 是“3 天以前”,不是“3 天内”;后者用 -3。
  5. find ... -delete 前先 -print 看一眼,防止误删。
  6. cmd > f 2>&1 与 cmd 2>&1 > f 结果不同,顺序决定重定向目标。
  7. sort f > f 会清空文件,写回用 -o。
  8. uniq 只能去相邻重复,必须先 sort。
  9. tar -f 后面必须紧跟包名,写成 tar -czvf a.tar.gz(v 在 f 前)。
  10. tar 打包时用绝对路径会带上一堆目录,建议 cd 到目标目录再用 ./*。
  11. split 合并依赖文件名顺序,自定义前缀要确认 cat 的顺序。
  12. curl ... | bash 等于执行陌生代码,先下载检查。

练习(18 题)

  1. 在 /etc 下查找文件名以 ifcfg- 开头的文件。
  2. 找出 /var/log 下大于 100M 的普通文件。
  3. 找出 /tmp 下 7 天以前修改过的 .log 文件,先只打印路径。
  4. 找出 /etc 下所有目录(不含文件),只看两层深度。
  5. 找出 /etc 下大于 3M 或者 以 .log 结尾的文件。
  6. 找出 /data 下比 /data/bak.tar.gz 更新的文件。
  7. 把 /etc 下 3M 以内的文件复制到 /test/,要求保留权限和时间戳。
  8. 把 /log 下大于 10M 的文件删除(一条命令)。
  9. 用 wget 把 http://nginx.org/download/nginx-1.22.1.tar.gz 下载到 /tmp 并命名为 nginx.tar.gz。
  10. 目标站点是自签证书,用 wget 和 curl 分别跳过证书校验下载文件。
  11. 用 curl 只看 https://www.baidu.com 的响应头。
  12. 把 command 的正常输出和错误输出都写入 /tmp/all.log(覆盖)。
  13. 把标准错误单独写入 /tmp/err.log,正常输出不要。
  14. 用 here-doc 往 /tmp/nginx.conf 写入三行内容,并保证变量不被展开。
  15. 统计 access.log 中访问次数最多的前 10 个 IP。
  16. 把 /data 打包成 /backup/data_2026_10_20.tar.gz(gzip),并且解压后不要多一层 data 目录。
  17. 把 /data 打成 zip,再解压到 /tmp/unzip_test。
  18. 把 5G 的 big.tar.gz 每 2M 切片,传完后合并并校验一致性。

答案与解析

1.

find /etc -name "ifcfg-*"

通配符加引号,避免被 shell 展开。

2.

find /var/log -type f -size +100M

-type f 排除目录;+100M 表示大于。

3.

find /tmp -name "*.log" -mtime +7 -print

确认无误后再把 -print 换成 -delete。

4.

find /etc -maxdepth 2 -type d

-maxdepth 放在 -type 前面。

5.

find /etc -size +3M -o -name "*.log"

-o 两侧条件满足一个即可;复杂组合用 \( \)。

6.

find /data -newer /data/bak.tar.gz

7.

find /etc -size -3M -exec cp -a {} /test/ \;

cp -a 保留元数据和内容;目标目录要先存在。

8.

find /log -size +10M -exec rm -rf {} \;

谨慎操作,建议先 -print 确认。

9.

wget -O /tmp/nginx.tar.gz http://nginx.org/download/nginx-1.22.1.tar.gz

10.

wget --no-check-certificate https://nginx.org/download/nginx-1.22.1.tar.gz
curl -k -O https://nginx.org/download/nginx-1.22.1.tar.gz

也可以改走 http:// 协议。

11.

curl -I https://www.baidu.com

-I 只发 HEAD 请求,显示响应头。

12.

command > /tmp/all.log 2>&1
# 或
command &> /tmp/all.log

13.

command 2> /tmp/err.log

只重定向 2,标准输出仍然到屏幕。

14.

cat > /tmp/nginx.conf << "EOF"
server {
    listen 80;
}
EOF

结束符加引号可阻止变量展开。

15.

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

16.

cd /data && tar -czf /backup/data_2026_10_20.tar.gz ./*

先进入目录再用 ./* 打包,解压后不会多一层 data/。

17.

zip -rq /backup/data.zip /data
unzip /backup/data.zip -d /tmp/unzip_test

18.

split -b 2M big.tar.gz
cat xa* > big2.tar.gz
md5sum big.tar.gz big2.tar.gz

两个 md5 相同即校验通过;也可以用 sha256sum。

我的笔记 · 生成于 2026-10-26 00:46