这是我复习《UNIX系统》这门课程时记录的一些笔记 ,希望能对你有所帮助😊
i 节点
理解 i 节点能帮助你更深入掌握 Linux 文件系统的工作原理!
在 Linux/Unix 文件系统中,i 节点(inode) 是文件系统的核心数据结构,它存储了文件的元数据(metadata),但==不包含文件名或文件内容本身==
1. i 节点的基本概念
(1)文件的组成
每个文件在文件系统中由 3 部分组成:
- 文件名(File Name):用户可见的名称(如
file1)。 - i 节点(inode):存储文件的元数据(权限、所有者、时间戳、数据块位置等)。
- 文件内容(Data Blocks):实际存储文件数据的磁盘块。
(2)查看文件的 i 节点
使用 ls -il 可以查看文件的 i 节点编号:
1 2
| $ ls -il 1234567 -rw-r--r-- 1 user group 1024 Jan 1 10:00 file1
|
1234567 是 file1 的 i 节点编号。- 其他信息(权限、所有者、大小、时间等)均存储在 i 节点中。
2. i 节点中存储的信息
每个 i 节点包含以下关键信息(通过 stat 命令可查看):
1 2 3 4 5 6 7 8
| $ stat file1 File: file1 Size: 1024 Blocks: 8 IO Block: 4096 regular file Device: 801h/2049d Inode: 1234567 Links: 1 Access: 2024-01-01 10:00:00.000000000 +0800 Modify: 2024-01-01 10:00:00.000000000 +0800 Change: 2024-01-01 10:00:00.000000000 +0800 Birth: -
|
| 字段 | 说明 |
|---|
| Inode 编号 | 文件的唯一标识(如 1234567)。 |
| 文件类型 | 普通文件、目录、符号链接等。 |
| 权限(Mode) | 如 -rw-r--r--(对应数字 644)。 |
| 所有者(UID) | 文件属主的用户 ID。 |
| 所属组(GID) | 文件属组的组 ID。 |
| 硬链接数(Links) | 指向该 i 节点的文件名数量(见下文)。 |
| 文件大小 | 字节数(如 1024)。 |
| 时间戳 | 访问时间(atime)、修改时间(mtime)、状态变更时间(ctime)。 |
| 数据块位置 | 文件内容存储在磁盘的哪些块中。 |
3. 硬链接(Hard Link)与 i 节点的关系
(1)创建硬链接
- 本质:
file1 和 file2 指向同一个 i 节点(如 1234567)。 - 效果:
- i 节点的 硬链接计数(Links) 从
1 变为 2。 - 修改
file1 或 file2 会同步更改文件内容(因为指向同一数据块)!!!
(2)删除硬链接
- 本质:仅删除
file2 这个文件名,i 节点(1234567)和数据块仍存在。 - 效果:
- i 节点的硬链接计数从
2 变回 1(file1 仍指向它)。
- 本质:i 节点的硬链接计数降为
0,系统自动回收该 i 节点及其数据块。
4. i 节点 vs 文件名
| 行为 | 对 i 节点的影响 |
|---|
| 创建文件 | 分配一个空闲 i 节点,初始化元数据,硬链接计数设为 1。 |
| 创建硬链接 | i 节点的硬链接计数 +1(多个文件名共享同一 i 节点)。 |
| 删除文件 | i 节点的硬链接计数 -1;若计数为 0,则释放 i 节点和数据块。 |
| 修改文件内容 | 更新 i 节点中的 mtime 和 ctime,但 i 节点编号不变。 |
| 重命名文件 | 仅修改文件名记录,不影响 i 节点。 |
5. 关键结论
- i 节点是文件的唯一标识
- 文件名只是 i 节点的“别名”,同一个文件可以有多个文件名(硬链接)
- 删除文件的实际过程
rm 只是减少 i 节点的硬链接计数,计数为 0 时才会真正删除文件。
- 硬链接的限制
- 不能跨文件系统(因为 i 节点编号仅在同一个文件系统内唯一)。
- 不能对目录创建硬链接(防止循环引用导致文件系统混乱)。
6. 扩展命令
| 命令 | 作用 |
|---|
ls -i | 显示文件的 i 节点编号。 |
df -i | 查看文件系统的 i 节点使用情况。 |
find / -inum 1234 | 通过 i 节点编号查找文件。 |
总结
- i 节点是文件的“身份证”,存储元数据但不含文件名或内容。
- 硬链接是多个文件名共享同一 i 节点,软链接(符号链接)则是==独立的文件(有自己的 i 节点),存储目标文件的路径(字符串)==
- 文件删除的本质是 减少 i 节点的硬链接计数,计数归零后系统才会回收资源。
文件编辑与流处理
ed编辑器
ed 是 Unix 历史上的里程碑式行编辑器,由 Ken Thompson 在 1970 年开发,其设计哲学深刻影响了后续工具(如 sed、vim)。以下是结合您提供的资料的系统性总结:
一、ed 的核心优势
极简主义
- 仅需 几 KB 内存 即可运行,适合救援模式或嵌入式系统。
- 无图形界面,所有操作通过命令驱动,可通过管道脚本化编辑。
正则表达式先驱
- 其正则语法(如
s/old/new/)被 sed、grep、perl 等工具继承,成为业界标准。
高效处理
- 直接按行操作,避免全文件加载,处理大文件时速度显著优于现代编辑器。
二、核心命令详解(按功能分类)
1. 导航与显示
| 命令 | 作用 | 示例 |
|---|
n | 跳转到第 n 行 | 5 → 跳转到第 5 行 |
.+3 | 相对行号(当前行+3) | .,.+5p → 显示后续 5 行 |
$ | 最后一行 | $p → 显示末行 |
,p | 显示全部内容 | 1,$p 等效 |
2. 编辑操作
| 命令 | 作用 | 结束符 |
|---|
a | 当前行后追加 | 独占一行的 . |
i | 当前行前插入 | 同上 |
m,nd | 删除 m 到 n 行 | 无 |
u | 撤销最后一次编辑 | 仅支持一级撤销 |
3. 搜索与替换
| 命令 | 关键细节 | 示例 |
|---|
/pattern/ | 向后搜索,循环至文件尾 | /main/ → 跳转到下一个 “main” |
?pattern? | 向前搜索,循环至文件头 | ?int? → 向上找 “int” |
s/old/new/[g] | g 表示全局替换 | s/cat/dog/g → 替换所有 “cat” |
& 占位符 | 引用匹配的文本 | s/big/very &/ → “big” → “very big” |
4. 文件操作
| 命令 | 说明 |
|---|
w [file] | 保存(可另存为) |
q | 安全退出(未保存时提示) |
Q | 强制退出(不保存) |
!cmd | 临时执行 shell 命令(如 !ls) |
三、经典使用场景
1. 脚本化编辑
1 2
| echo -e "1,\$s/foo/bar/g\nwq" | ed file.txt
|
2. 精准行操作
1 2
| echo -e "/debug/,+2d\nwq" | ed log.txt
|
3. 正则表达式测试
1 2
| echo -e "/error/,\$p\nq" | ed app.log
|
四、与现代工具对比
| 特性 | ed | sed/vim |
|---|
| 交互性 | 极低(纯命令) | 中/高 |
| 学习曲线 | 陡峭 | 中等 |
| 适用场景 | 脚本化、救援模式 | 日常编辑 |
| 正则支持 | 基础 | 扩展(如 \d) |
五、操作流程图解
1 2 3 4 5
| 启动 ed → [命令模式] ├─ 导航 (n, $, .) ├─ 编辑 (a/i, d, s) ├─ 搜索 (/pattern/, ?pattern?) └─ 保存退出 (wq)
|
六、为什么今天仍值得了解?
- 理解 Unix 哲学:
ed 是“工具链组合”思想的典范(与 grep、awk 协同)。 - 应急修复:当系统仅剩
/bin/ed 可用时,它是最后的编辑手段。 - 历史教育:通过
ed 可直观看到现代编辑器的演进路径。
若需快速上手实用编辑,推荐 nano 或 vim;但掌握 ed 如同学习汇编语言,能加深对计算本质的理解。
正则表达式
ed 正则表达式核心知识点
1. 元字符与转义
| 语法 | 作用 | 示例 |
|---|
普通字符 | 匹配自身(如 a、1) | cat → 匹配 “cat” |
\c | 取消字符 c 的特殊意义 | \* → 匹配字面 * |
^ | 行首(仅模式起始处有效) | ^hello → 行首的 “hello” |
$ | 行尾(仅模式结束处有效) | end$ → 行尾的 “end” |
. | 匹配任意单个字符 | a.c → “abc”, “a c” |
2. 字符类
| 语法 | 作用 | 示例 |
|---|
[...] | 匹配括号内任一字符 | [aeiou] → 任意元音 |
[^...] | 匹配不在括号内的字符 | [^0-9] → 非数字 |
[a-z] | 字符范围(支持连字符 -) | [A-Z] → 大写字母 |
3. 重复与分组
| 语法 | 作用 | 示例 |
|---|
r* | 0 次或多次匹配 r | a* → “”, “a”, “aa” |
.* | 匹配任意长度字符串 | ^a.*z$ → “a开头到z结尾的整行” |
& | 替换时引用匹配的文本 | s/cat/&s/ → “cat”→”cats” |
4. 常用模式示例
| 模式 | 匹配目标 |
|---|
^$ | 空行(开头即结尾) |
^# | 以 # 开头的行(如注释) |
\.$ | 以点号结尾的行 |
/[tT]est/ | “test” 或 “Test” |
[0-9][0-9]* | 至少一个数字 |
^[^a-zA-Z] | 不以字母开头的行 |
/thing.$/ | 以thing加任意符号结尾的行 |
5. 全局命令 (g/v)
- 命令格式:m,ng/re/cmd,含义是从m行到n行中对于匹配re模式的行执行命令cmd. 如果作用范围是全文件(1,$),m、n可以省略
| 命令格式 | 作用 | 示例 |
|---|
g/re/p | 打印匹配 re 的行 | g/error/p → 显示含 “error” 的行 |
g/re/d | 删除匹配 re 的行 | g/^$/d → 删除所有空行 |
g/re/s/old/new/ | 对匹配 re 的行替换 old→new | g/foo/s/bar/baz/ → 仅替换含 “foo” 的行中的 “bar” |
v/re/p | 取反操作(不匹配 re 的行) | v/^$/p → 打印非空行 |
6. 移动与复制
| 命令格式 | 作用 | 示例 |
|---|
m,nmd | 将 m 到 n 行移动到 d 行后 | 2,4m5 → 2-4 行移到第 5 行后 |
m,ntd | 将 m 到 n 行复制到 d 行后 | 1,3t$ → 复制 1-3 行到文件末尾 |
g/^/m0 | 反转文件行序(每行移到第 0 行后) | 结果:最后一行变第一行 |
关键注意事项
- 贪婪匹配:
r* 是贪婪的(尽可能多匹配)。 - 转义特殊字符:如
\. 匹配字面点号,\\ 匹配反斜杠。 - 全局命令范围:省略
m,n 时默认全文件(1,$)。 - **替换中的
&**:仅在 s/// 右侧有效,代表匹配的全文。
ed 的正则为现代工具(如 sed/grep)奠定了基础,虽功能有限,但足够处理基础文本操作。
sed流编辑器
以下是结合参考文献对sed知识点的系统总结,关键部分标注引用来源:
sed核心特性
流编辑器本质
- 直接从
ed发展而来,专为处理输入流设计(文件或管道数据) - 单次扫描输入流,高效但无法回溯已处理行(局限性)
- 默认输出到stdout且不修改原文件(需重定向保存结果)
基础语法结构
1
| sed [选项] '编辑命令1;编辑命令2' 输入文件
|
- 经典示例:
sed 's/UNIX/Linux/g' file 全局替换文本 - 支持多命令组合:
sed 's/foo/bar/; 10q' file(替换+显示前10行)
常用操作场景
| 功能 | 命令示例 | 说明 |
|---|
| 文本替换 | sed 's/old/new/g' file | 全局替换(加g标志) |
| 行范围操作 | sed '10q' file | 显示前10行(q退出命令) |
| 模式过滤 | sed -n '/pattern/p' file | 仅显示匹配行(-n关闭默认输出,等效grep) |
| 目录列表过滤 | `ls -l | sed -n ‘/^d/p’` |
| 多模式范围输出 | sed -n '/start/,/end/p' file | 打印两个模式间的所有行(如/David/,/Emily/p) |
关键选项与限制
选项
-n:抑制默认输出,需显式用p命令打印-e:指定多个编辑命令(如sed -e 's/a/b/' -e 's/c/d/')
局限性
- 无法行运算:如
$-1d非法,因sed是单向流处理器 - 无交互模式:所有操作需通过命令预设
与管道的协同
动态处理流数据:
组合其他命令:
1
| grep "error" log.txt | sed 's/ERROR/CRITICAL/g'
|
扩展应用
批量编辑文件:
1
| sed -i.bak 's/old/new/g' *.txt
|
条件删除:
设计哲学
- UNIX工具链思维:专注单一功能(文本转换),通过管道与其他工具(如
grep、awk)协作[][6] - 高效性:单次流处理比交互式编辑器更适合自动化任务[][6]
通过掌握这些核心模式,可高效完成90%的文本处理需求。进阶学习可参考GNU sed手册[6]中的正则表达式和保持空间(hold space)技巧。
grep过滤器
grep 是 Linux/Unix 中最强大的文本过滤工具之一,常与管道符 | 和其他命令(如 ls、sed、sort)结合使用
1. grep 基础语法
- 核心功能:从文件或输入流中筛选包含指定模式的行。
- 常用选项:
-i:忽略大小写(如 grep -i "error" log.txt)。-v:反向匹配(显示不包含模式的行)。-n:显示匹配行的行号。-c:统计匹配行的数量。-r:递归搜索目录(如 grep -r "main" /src)。
示例 1:搜索文件内容
- 作用:在
sig.c 文件中查找以 void 开头的行。
示例 2:过滤目录
- 作用:列出当前目录下的子目录(不包括文件)。
- 原理:
ls -l 的输出中,目录行以 d 开头(如 drwxr-xr-x)。^d 匹配行首的 d 字符。
示例 3:提取目录名
1
| ls -l | grep '^d' | sed 's/.* //'
|
- 作用:仅输出子目录名(去掉权限、时间等冗余信息)。
- 分步解析:
ls -l | grep '^d':筛选目录行。sed 's/.* //':删除行中最后一个空格前的所有内容(保留目录名)。
3. grep 家族对比
| 命令 | 全称 | 特点 |
|---|
grep | Global Regular Expression Print | 基础版,支持基本正则表达式(BRE)。 |
egrep | Extended GREP | 支持扩展正则表达式(ERE),如 +、?、` |
fgrep | Fixed-string GREP | 仅匹配固定字符串(不支持正则),但处理大文件时速度最快。 |
典型场景
egrep 的扩展功能:1
| egrep 'error|warn' log.txt
|
fgrep 的高效性:1
| fgrep -c "404" access.log
|
4. 结合其他过滤器
4.1 sort(排序)
1 2
| ls | sort grep "error" log.txt | sort -u
|
4.2 head / tail(首尾行)
1 2
| grep "Exception" server.log | tail -5 grep "login" auth.log | head -3
|
4.3 组合实战
1 2
| grep -o "ERROR: .*" app.log | sort | uniq -c | sort -nr | head -5
|
- 步骤分解:
grep -o:提取所有 ERROR: xxx 内容。sort:排序以便 uniq 统计。uniq -c:计数。sort -nr:按计数降序。head -5:显示前5条。
总结
grep:文本过滤的瑞士军刀,核心是模式匹配。- 管道组合:与
sed、sort、head/tail 联动可解决复杂问题。 - 选择工具:
- 简单搜索 →
grep 或 fgrep。 - 复杂正则 →
egrep。 - 需排序/统计 → 结合
sort | uniq -c。