Linux: 文件与目录操作——创建 / 复制 / 移动 / 删除
在 Linux 终端中,创建、复制、移动和删除文件都是敲几个键的事——比鼠标快得多,也更精确。
📋 前置知识:需要先掌握以下内容
- 第4课:文件系统导航
1. 你将学到
- touch 创建文件和更新时间戳
- mkdir 创建目录(含 -p 递归)
- cp 复制文件和目录
- mv 移动和重命名
- rm 安全删除(含 -rf 风险警示)
2. 一根筋的小明学会了一行创建整个项目结构
(1) 痛点:每次创建目录都要层层右键
小明想创建一个项目目录结构 myblog/src/css、myblog/src/js、myblog/docs。他在 Windows 上右键→新建文件夹,一层层创建,每次重复劳动。
(2) 一行命令创建整个结构
资深工程师 Bob 在他终端上输入了一行:
BASH
mkdir -p myblog/{src/{css,js,img},docs}
回车后 tree myblog 显示:
TEXT
📖 仅展示
myblog/
├── src/
│ ├── css/
│ ├── js/
│ └── img/
└── docs/
小明目瞪口呆。他终于理解了为什么开发者喜欢用终端。
(3) 收益:操作效率飙升
小明学会了文件操作的五大命令后,创建和整理文件的速度从"分钟级"降到了"秒级"。
3. 知识点讲解
(1) touch——创建文件或更新时间戳
BASH
touch filename
如果文件不存在,touch 创建一个空文件。如果文件存在,它的访问和修改时间更新为当前时间。
(2) mkdir——创建目录
BASH
mkdir dirname # 创建单个目录
mkdir -p a/b/c # 递归创建(上级目录不存在时自动创建)
mkdir dir1 dir2 dir3 # 一次创建多个目录
mkdir -p src/{css,js} # 花括号展开批量创建
> 💡 **提示**:`mkdir -p` 配合花括号展开 `{a,b,c}` 是 bash 的高效组合——`mkdir -p project/{src/{css,js},docs}` 一行命令就能创建整个项目目录树,比逐层创建快得多。
(3) cp——复制
BASH
cp source destination # 复制文件
cp -r source_dir dest_dir # 递归复制目录
cp -i source destination # 交互模式(覆盖前确认)
cp -u source destination # 仅当源文件更新时才复制
cp -v source destination # 显示复制过程
cp -p source destination # 保留文件属性(权限/时间戳)
(4) mv——移动和重命名
BASH
mv oldname newname # 重命名
mv file.txt /path/to/dest/ # 移动文件到其他目录
mv dir1 dir2 # 如果 dir2 不存在则重命名,存在则移入
mv -i source dest # 覆盖前确认
mv -u source dest # 仅当源文件更新时才移动
(5) rm——删除
BASH
rm file.txt # 删除文件
rm -r dirname # 递归删除目录
rm -f file.txt # 强制删除(不提示确认)
rm -i file.txt # 交互模式(删除前确认)
rm -rf dirname # 递归强制删除(⚠️ 危险组合)
⚠️ 安全警告:
rm -rf / 会删除整个系统。永远不要以 root 身份运行 rm -rf /。日常操作养成用 -i 的习惯。
⚠️ 注意:
rm -rf 删除的文件不会进入回收站,无法通过常规方式恢复。在使用 rm -rf 前,务必确认当前目录(pwd)和要删除的路径,避免误删。建议在 .bashrc 中添加 alias rm='rm -i' 作为安全网。
(6) 硬链接 vs 软链接
| 特性 | 硬链接 | 软链接(符号链接) |
|---|---|---|
| 命令 | ln target link_name |
ln -s target link_name |
| inode | 与原文件相同 | 不同 |
| 跨文件系统 | 否 | 是 |
| 目录 | 否 | 是 |
| 原文件删除后 | 链接仍可用 | 链接失效(断链) |
| 文件大小 | 同原文件 | 仅存储路径字符串 |
TEXT
📖 仅展示
# 硬链接
ln original.txt hardlink.txt
# 软链接
ln -s /usr/bin/python3 python3
▶ 示例:创建文件和目录
BASH
# 创建空文件
touch index.html
touch style.css script.js # 一次创建多个
# 创建目录
mkdir projects
mkdir -p projects/web/src/css # 递归创建嵌套目录
# 花括号展开(bash 特性)
mkdir -p {2024,2025,2026}/{01,02,03}
# 创建:2024/01, 2024/02, 2024/03, 2025/01, ...
输出:
TEXT 📖 仅展示2024: 01 02 03 2025: 01 02 03 2026: 01 02 03
▶ 示例:复制文件
BASH
# 复制单个文件
cp index.html index.backup.html
# 复制目录(需要 -r)
cp -r projects projects-backup
# 交互模式,防止意外覆盖
cp -i important.txt /backup/
# 保留文件属性
cp -p config.conf /backup/
输出:
TEXT 📖 仅展示cp: overwrite '/backup/important.txt'? n
▶ 示例:移动和重命名
BASH
# 重命名文件
mv old-report.md report-2026.md
# 移动到其他目录
mv report.md ~/Documents/reports/
# 批量重命名(使用循环)
for f in *.html; do mv "$f" "${f%.html}.htm"; done
输出:
TEXT 📖 仅展示(无输出,文件已重命名)
▶ 示例:安全删除
TEXT
📖 仅展示
# 安全第一:交互模式
rm -i file.txt
# 删除空目录
rmdir empty-dir
# 删除非空目录
rm -r old-project/
# 谨慎使用(会直接删除不提示)
rm -f temp.log
▶ 示例:使用通配符批量操作
BASH
# 复制所有 .jpg 文件
cp *.jpg ~/Pictures/
# 删除所有 .tmp 临时文件
rm *.tmp
# 移动以 2024 开头的文件
mv 2024* ~/archive/
# 列出以数字结尾的文件
ls *[0-9]
输出:
TEXT 📖 仅展示report2024.md log2025.txt backup1.tar.gz
▶ 综合示例:创建完整的项目目录结构
BASH
# 小明创建他的博客项目(一行搞定)
mkdir -p myblog/{src/{css,js,img},docs,scripts,test}
# 在 src 下创建一个 HTML 索引文件
touch myblog/src/index.html
# 复制一份作为备份
cp -r myblog myblog-backup
# 重命名备份目录
mv myblog-backup myblog-2026-07
# 查看最终结构
find myblog -type f -o -type d | sort
❓ 常见问题
Q:
rm -rf /真的会删光整个系统吗? A: \1
Q: cp 和 mv 对目录操作有什么区别? A:
cp需要-r参数才能复制目录(递归)。mv不需要——移动目录和移动文件是一样的命令。如果目标目录不存在,mv会重命名;如果存在,会将源移入目标内部。
Q: 文件名有空格怎么处理? A: \1
Q: 怎么批量重命名文件? A: 用
for循环:for f in *.jpg; do mv "$f" "prefix_$f"; done,或用专有工具rename:rename 's/\.jpg$/\.png/' *.jpg。
Q: 软链接删掉原文件会怎样? A: 软链接变成"断链"(broken link)——
ls -l会显示红底闪烁的名字,访问它会提示No such file or directory。硬链接不受影响(因为它直接指向原文件的 inode)。
📖 小节
touch创建空文件,mkdir -p创建递归目录cp -r复制目录,mv移动或重命名,rm -r删除目录- 花括号展开
{a,b,c}可以批量创建 ln创建硬链接,ln -s创建软链接rm -rf是危险组合——永远确认当前目录和身份再执行
📝 作业
- 基础题(难度⭐):用
mkdir -p创建目录树linux/assignments/{hw1,hw2,hw3}/{src,docs},并在每个 hw 的 src 下用花括号展开创建main.py - 进阶题(难度⭐⭐):将 hw3 复制为 hw4 并验证,然后删除 hw1/src/main.py,用
rm -r删除 hw2 整个目录 - 挑战题(难度⭐⭐⭐):创建一个软链接指向
/etc/hostname并验证,然后写一行命令用find找出你刚才创建的所有main.py文件并批量重命名为main.sh