2041_22T2.Q2
一、 读题与需求拆解
1. 数据结构分析:
输入数据通过标准输入 (< enrollments.txt) 传入,为标准的管道符 | 分隔文件,共 5 个字段。
例如:COMP1917|3360379|Costner, Kevin Augustus |3978/1|M
- 字段 3 (Name):内部具有二级结构,格式为
[Surname], [First Names]。 - 字段 5 (Gender):标识性别,男性为
M。
2. 目标输出:
- 过滤条件:仅限男性 (
male/M)。 - 提取目标:仅提取姓氏 (
Surname)。 - 后处理:去重 (
printed only once) 且按字母序排列 (alphabetical order)。
3. 硬性约束(Technical Constraints):
- 必须是单一的 Shell pipeline。
- 只能使用基础 UNIX 过滤器(如
grep,cut,sort等)。
二、 技术路线设计
- 行级过滤 (Row Filtering):先用
grep剔除无关行。 - 一级字段提取 (Primary Extraction):用
cut按|分割,提取包含姓名的整个第 3 列。 - 二级字段提取 (Secondary Extraction):改变分隔符,再次用
cut按,分割,精准剥离出姓氏。 - 排序去重 (Sorting & Deduplication):使用
sort处理最终文本。
三、 最终脚本与逐级解析
命令实现:
1 |
|
数据流逐级剖析:
grep '|M$'- 作用:精确过滤男性学生记录。
- 原理:如果不加修饰直接使用
grep 'M',会误命中姓名或课程号中带有 M 的行(如Mary或COMP3891)。使用$锚定行尾,并带上前置分隔符|,构成极严谨的正则表达式,确保只匹配最后一个字段确切为M的行。
cut -d'|' -f3- 作用:提取完整的姓名列。
- 原理:指定分隔符为管道符 (
-d'|'),提取第 3 个字段 (-f3)。此时数据流从完整的注册记录变为了纯姓名列表(如Costner, Kevin Augustus)。
cut -d',' -f1- 作用:从姓名中剥离出姓氏。
- 原理:由于数据规范中明确说明了姓氏由逗号分隔,此时动态切换定界符。指定逗号为分隔符 (
-d',') 并提取第 1 个字段 (-f1)。截断逗号及其后方的所有字符,数据流此时仅剩姓氏。
sort -u- 作用:字典序排序并去重。
- 原理:
sort默认按 ASCII 字母表顺序对文本行进行排列。附加-u(unique) 参数,等效于sort | uniq管道,在 O(N log N) 的排序过程中顺便完成 O(N) 的去重操作,满足输出规范要求。