简介
当 shell 协调多个命令时,即使是简单的 Linux 命令也能发挥更大作用。命令通过退出状态报告成功或失败;序列运算符决定接下来运行哪个命令;管道则把一个命令的标准输出连接到另一个命令的标准输入。
你将逐层学习这些概念,然后使用 grep、cut、wc、sort 和 uniq 处理一组小型服务事件数据。后续的文本处理实验会进一步讲解这些过滤器,因此本实验重点关注数据和决策如何在命令之间传递。
观察命令的退出状态
在本步骤中,你将把命令的可见行为与 shell 记录的数值状态联系起来。
退出状态为 0 表示成功;非零值表示命令无法完成请求的操作。先执行一次成功的文件测试,然后立即输出 $?。$? 保存最近一次命令的状态:
cd /home/labex/project/pipeline-lab
test -f events.csv
echo $?
输出为 0。现在测试一个不存在的文件:
test -f missing.csv
echo $?
此时状态为非零值。要立即读取 $?,因为之后执行的每个命令都会替换它。
使用 if 语句创建一个稳定的观察结果。你将在后续学习完整的 shell 脚本;这里的 if 语句只负责把状态转换为文本:
if test -f events.csv; then echo "events.csv is ready"; else echo "events.csv is missing"; fi > status-result.txt
cat status-result.txt
控制接下来运行哪个命令
在本步骤中,你将比较无条件命令运算符和条件命令运算符。
分号会无条件运行下一个命令,不论上一个命令的结果如何:
false; echo "semicolon continues"
&& 只有在左侧命令成功后才会运行右侧命令:
test -f events.csv && echo "input found"
test -f missing.csv && echo "you should not see this"
|| 只有在左侧命令失败后才会运行右侧命令:
test -f missing.csv || echo "input missing"
这些运算符可以表达一个简单的成功或失败判断。仅当数据集存在时复制它,否则输出错误信息:
test -f events.csv && cp events.csv working.csv || echo "Copy failed"
验证受条件保护的副本是否与源文件一致:
cmp events.csv working.csv && echo "guarded copy matches" > sequence-result.txt
cat sequence-result.txt
对于复杂逻辑,优先使用易读的 if 语句;过长的 &&/|| 链可能产生歧义。
通过管道传递输出
在本步骤中,你将使用 | 连接命令,并观察每个阶段如何逐步缩小数据流。
左侧命令会把标准输出写入管道;右侧命令会把这些数据作为标准输入读取。只选择 ERROR 记录:
cd /home/labex/project/pipeline-lab
cat events.csv | grep ',ERROR,'
grep 可以直接读取文件,因此下面这种更短的写法会产生相同结果:
grep ',ERROR,' events.csv
添加 wc -l,统计匹配的行数:
grep ',ERROR,' events.csv | wc -l
同时保存过滤后的数据流及其计数结果。tee 会复制标准输入:它将一份副本写入 error-events.csv,并通过标准输出把另一份副本继续传递下去。因此,最后的 wc -l 统计的正好是已保存的行数:
grep ',ERROR,' events.csv | tee error-events.csv | wc -l > error-count.txt
cat error-events.csv
cat error-count.txt
管道执行后检查这两个文件。error-events.csv 包含匹配的记录,error-count.txt 包含这些记录的数量。
使用 Cut 提取字段
在本步骤中,你将把每一行 CSV 数据视为由分隔符分开的字段。
cut -d, -f1 使用逗号作为分隔符,并输出第 1 个字段,即服务名称:
cd /home/labex/project/pipeline-lab
cut -d, -f1 events.csv
同时输出服务名称和严重级别字段:
cut -d, -f1,2 events.csv
组合使用过滤和提取操作,仅列出产生警告的服务:
grep ',WARN,' events.csv | cut -d, -f1
保存这个中间结果:
grep ',WARN,' events.csv | cut -d, -f1 > warning-services.txt
cat warning-services.txt
对于字段内部不包含分隔符的简单记录,cut 效果很好。更复杂的格式可能需要使用 awk 或支持相应格式的工具。
排序并统计重复值
在本步骤中,你将构建完整的频率统计管道,并理解为什么必须先排序再使用 uniq。
uniq 只能合并相邻的相同行。先提取服务名称,再对其排序,使相同的值彼此相邻:
cd /home/labex/project/pipeline-lab
cut -d, -f1 events.csv | sort
添加 uniq -c,统计每组相同名称的数量:
cut -d, -f1 events.csv | sort | uniq -c
按数字降序排列统计结果。sort -k1,1nr 使用第一个字段作为数字逆序排序键:
cut -d, -f1 events.csv | sort | uniq -c | sort -k1,1nr
保存最终报告:
cut -d, -f1 events.csv | sort | uniq -c | sort -k1,1nr > service-frequency.txt
cat service-frequency.txt
从左到右阅读这条管道:提取 → 排序 → 统计相邻重复项 → 按数量排名。
总结
你使用退出状态表示 shell 中的成功结果,使用 ;、&& 和 || 控制命令执行,并构建了包含清晰阶段的管道。随后,你过滤了记录、提取了字段、统计了行数、对值进行了排序并统计了重复项——这些正是下一个数据管道挑战所需的基础操作。



