UNIX系统复习-2

这是我复习《UNIX系统》这门课程时记录的一些笔记 ,希望能对你有所帮助😊

i 节点

理解 i 节点能帮助你更深入掌握 Linux 文件系统的工作原理!

在 Linux/Unix 文件系统中,i 节点(inode) 是文件系统的核心数据结构,它存储了文件的元数据(metadata),但==不包含文件名或文件内容本身==


1. i 节点的基本概念

(1)文件的组成

每个文件在文件系统中由 3 部分组成:

  1. 文件名(File Name):用户可见的名称(如 file1)。
  2. i 节点(inode):存储文件的元数据(权限、所有者、时间戳、数据块位置等)。
  3. 文件内容(Data Blocks):实际存储文件数据的磁盘块。

(2)查看文件的 i 节点

使用 ls -il 可以查看文件的 i 节点编号:

1
2
$ ls -il
1234567 -rw-r--r-- 1 user group 1024 Jan 1 10:00 file1
  • 1234567file1 的 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)创建硬链接

1
$ ln file1 file2  # 为 file1 的 i 节点增加一个新文件名 file2
  • 本质file1file2 指向同一个 i 节点(如 1234567)。
  • 效果
    • i 节点的 硬链接计数(Links)1 变为 2
    • 修改 file1file2 会同步更改文件内容(因为指向同一数据块)!!!

(2)删除硬链接

1
$ rm file2  # 删除文件名 file2
  • 本质:仅删除 file2 这个文件名,i 节点(1234567)和数据块仍存在。
  • 效果
    • i 节点的硬链接计数从 2 变回 1file1 仍指向它)。
1
$ rm file1  # 删除最后一个文件名 file1
  • 本质:i 节点的硬链接计数降为 0,系统自动回收该 i 节点及其数据块。

4. i 节点 vs 文件名

行为对 i 节点的影响
创建文件分配一个空闲 i 节点,初始化元数据,硬链接计数设为 1
创建硬链接i 节点的硬链接计数 +1(多个文件名共享同一 i 节点)。
删除文件i 节点的硬链接计数 -1;若计数为 0,则释放 i 节点和数据块。
修改文件内容更新 i 节点中的 mtimectime,但 i 节点编号不变。
重命名文件仅修改文件名记录,不影响 i 节点。

5. 关键结论

  1. i 节点是文件的唯一标识
    • 文件名只是 i 节点的“别名”,同一个文件可以有多个文件名(硬链接)
  2. 删除文件的实际过程
    • rm 只是减少 i 节点的硬链接计数,计数为 0 时才会真正删除文件。
  3. 硬链接的限制
    • 不能跨文件系统(因为 i 节点编号仅在同一个文件系统内唯一)。
    • 不能对目录创建硬链接(防止循环引用导致文件系统混乱)。

6. 扩展命令

命令作用
ls -i显示文件的 i 节点编号。
df -i查看文件系统的 i 节点使用情况。
find / -inum 1234通过 i 节点编号查找文件。

总结

  • i 节点是文件的“身份证”,存储元数据但不含文件名或内容。
  • 硬链接是多个文件名共享同一 i 节点,软链接(符号链接)则是==独立的文件(有自己的 i 节点),存储目标文件的路径(字符串)==
  • 文件删除的本质是 减少 i 节点的硬链接计数,计数归零后系统才会回收资源。

文件编辑与流处理

ed编辑器

ed 是 Unix 历史上的里程碑式行编辑器,由 Ken Thompson 在 1970 年开发,其设计哲学深刻影响了后续工具(如 sedvim)。以下是结合您提供的资料的系统性总结:


一、ed 的核心优势

  1. 极简主义

    • 仅需 几 KB 内存 即可运行,适合救援模式或嵌入式系统。
    • 无图形界面,所有操作通过命令驱动,可通过管道脚本化编辑。
  2. 正则表达式先驱

    • 其正则语法(如 s/old/new/)被 sedgrepperl 等工具继承,成为业界标准。
  3. 高效处理

    • 直接按行操作,避免全文件加载,处理大文件时速度显著优于现代编辑器。

二、核心命令详解(按功能分类)

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
# 删除包含 "debug" 的行及其后 2 行
echo -e "/debug/,+2d\nwq" | ed log.txt

3. 正则表达式测试

1
2
# 测试正则匹配范围(显示首次 "error" 到文件末尾)
echo -e "/error/,\$p\nq" | ed app.log

四、与现代工具对比

特性edsed/vim
交互性极低(纯命令)中/高
学习曲线陡峭中等
适用场景脚本化、救援模式日常编辑
正则支持基础扩展(如 \d

五、操作流程图解

1
2
3
4
5
启动 ed → [命令模式] 
├─ 导航 (n, $, .)
├─ 编辑 (a/i, d, s)
├─ 搜索 (/pattern/, ?pattern?)
└─ 保存退出 (wq)

六、为什么今天仍值得了解?

  1. 理解 Unix 哲学ed 是“工具链组合”思想的典范(与 grepawk 协同)。
  2. 应急修复:当系统仅剩 /bin/ed 可用时,它是最后的编辑手段。
  3. 历史教育:通过 ed 可直观看到现代编辑器的演进路径。

若需快速上手实用编辑,推荐 nanovim;但掌握 ed 如同学习汇编语言,能加深对计算本质的理解。

正则表达式

ed 正则表达式核心知识点


1. 元字符与转义

语法作用示例
普通字符匹配自身(如 a1cat → 匹配 “cat”
\c取消字符 c 的特殊意义\* → 匹配字面 *
^行首(仅模式起始处有效)^hello → 行首的 “hello”
$行尾(仅模式结束处有效)end$ → 行尾的 “end”
.匹配任意单个字符a.c → “abc”, “a c”

2. 字符类

语法作用示例
[...]匹配括号内任一字符[aeiou] → 任意元音
[^...]匹配不在括号内的字符[^0-9] → 非数字
[a-z]字符范围(支持连字符 -[A-Z] → 大写字母

3. 重复与分组

语法作用示例
r*0 次或多次匹配 ra* → “”, “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 的行替换 oldnewg/foo/s/bar/baz/ → 仅替换含 “foo” 的行中的 “bar”
v/re/p取反操作(不匹配 re 的行)v/^$/p → 打印非空行

6. 移动与复制

命令格式作用示例
m,nmdmn移动d 行后2,4m5 → 2-4 行移到第 5 行后
m,ntdmn复制d 行后1,3t$ → 复制 1-3 行到文件末尾
g/^/m0反转文件行序(每行移到第 0 行后)结果:最后一行变第一行

关键注意事项

  1. 贪婪匹配r* 是贪婪的(尽可能多匹配)。
  2. 转义特殊字符:如 \. 匹配字面点号,\\ 匹配反斜杠。
  3. 全局命令范围:省略 m,n 时默认全文件(1,$)。
  4. **替换中的 &**:仅在 s/// 右侧有效,代表匹配的全文。

ed 的正则为现代工具(如 sed/grep)奠定了基础,虽功能有限,但足够处理基础文本操作。

sed流编辑器

以下是结合参考文献对sed知识点的系统总结,关键部分标注引用来源:


sed核心特性

  1. 流编辑器本质

    • 直接从ed发展而来,专为处理输入流设计(文件或管道数据)
    • 单次扫描输入流,高效但无法回溯已处理行(局限性)
    • 默认输出到stdout且不修改原文件(需重定向保存结果)
  2. 基础语法结构

    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 -lsed -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
    who | sed 's/ .*//'  # 提取用户名(删除首个空格后的所有内容)
  • 组合其他命令

    1
    grep "error" log.txt | sed 's/ERROR/CRITICAL/g'  # 二次过滤替换

扩展应用

  • 批量编辑文件

    1
    sed -i.bak 's/old/new/g' *.txt  # 直接修改文件并备份(`-i`选项)
  • 条件删除

    1
    sed '/pattern/d' file  # 删除匹配行(如空行`/^$/d`)

设计哲学

  • UNIX工具链思维:专注单一功能(文本转换),通过管道与其他工具(如grepawk)协作[][6]
  • 高效性:单次流处理比交互式编辑器更适合自动化任务[][6]

通过掌握这些核心模式,可高效完成90%的文本处理需求。进阶学习可参考GNU sed手册[6]中的正则表达式和保持空间(hold space)技巧。

grep过滤器

grep 是 Linux/Unix 中最强大的文本过滤工具之一,常与管道符 | 和其他命令(如 lssedsort)结合使用


1. grep 基础语法

1
grep [选项] '搜索模式' 文件名
  • 核心功能:从文件或输入流中筛选包含指定模式的行
  • 常用选项
    • -i:忽略大小写(如 grep -i "error" log.txt)。
    • -v:反向匹配(显示不包含模式的行)。
    • -n:显示匹配行的行号。
    • -c:统计匹配行的数量。
    • -r:递归搜索目录(如 grep -r "main" /src)。

示例 1:搜索文件内容

1
grep '^void' sig.c
  • 作用:在 sig.c 文件中查找void 开头的行

示例 2:过滤目录

1
ls -l | grep '^d'
  • 作用:列出当前目录下的子目录(不包括文件)。
  • 原理
    • ls -l 的输出中,目录行以 d 开头(如 drwxr-xr-x)。
    • ^d 匹配行首的 d 字符。

示例 3:提取目录名

1
ls -l | grep '^d' | sed 's/.* //'
  • 作用:仅输出子目录名(去掉权限、时间等冗余信息)。
  • 分步解析
    1. ls -l | grep '^d':筛选目录行。
    2. sed 's/.* //'删除行中最后一个空格前的所有内容(保留目录名)。

3. grep 家族对比

命令全称特点
grepGlobal Regular Expression Print基础版,支持基本正则表达式(BRE)。
egrepExtended GREP支持扩展正则表达式(ERE),如 +?、`
fgrepFixed-string GREP仅匹配固定字符串(不支持正则),但处理大文件时速度最快[2]

典型场景

  1. egrep 的扩展功能
    1
    egrep 'error|warn' log.txt  # 同时匹配 "error" 或 "warn"
  2. fgrep 的高效性
    1
    fgrep -c "404" access.log  # 快速统计 404 错误出现的次数

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  # 显示最后5个异常
grep "login" auth.log | head -3 # 显示前3次登录记录

4.3 组合实战

1
2
# 统计日志中每个错误类型的出现次数(排序后取前5)
grep -o "ERROR: .*" app.log | sort | uniq -c | sort -nr | head -5
  • 步骤分解
    1. grep -o:提取所有 ERROR: xxx 内容。
    2. sort:排序以便 uniq 统计。
    3. uniq -c:计数。
    4. sort -nr:按计数降序。
    5. head -5:显示前5条。

总结

  • grep:文本过滤的瑞士军刀,核心是模式匹配
  • 管道组合:与 sedsorthead/tail 联动可解决复杂问题。
  • 选择工具
    • 简单搜索 → grepfgrep
    • 复杂正则 → egrep
    • 需排序/统计 → 结合 sort | uniq -c
  1. egrep 相当于 grep -E,支持 |(或)、+(1次或多次)等扩展语法。
  2. fgrep 相当于 grep -F,适合精确匹配固定字符串(如日志中的错误码)。

UNIX系统复习-2
http://pzhwuhu.github.io/2025/05/30/UNIX系统复习-2/
本文作者
pzhwuhu
发布于
2025年5月30日
更新于
2025年5月30日
许可协议