玩转 Linux 命令行:文本过滤器入门

发布于 2025-09-27 分类: Linux

神奇的文本“过滤器”!

化繁为简,将原始数据变为有用信息。

引言

Linux 有一个非常核心的设计哲学:每个工具只做一件事,并把它做到极致。我们可以像搭积木一样,将这些小工具自由组合,搭建出功能强大的“城堡”。

在本章节中,我们将认识一些基础的“小积木”——文本过滤器。稍后,在更进阶的章节里,我们会学习如何将它们串联起来,完成更复杂的自动化任务。

别看这篇文章有点长,它大部分内容都是示例,所以请放轻松,并没有看起来那么吓人。

那么,什么是过滤器?

在 Linux 命令行中,“过滤器”(Filter)就是一个程序,它接收文本数据作为输入,经过一系列处理后,再输出处理过的新文本数据。

想象一个漏斗,你把一堆混杂着沙子和石头的混合物倒进去,漏斗会帮你把沙子筛出来。这里的“漏斗”就是过滤器。它能帮你从海量原始数据中,提取、整理、转换出你真正需要的信息。

这些过滤器通常都带有丰富的命令行选项,可以微调它们的功能。所以,遇到问题时,随时查阅 man 手册(man 命令名)是个好习惯。

在下面的例子中,我们会从一个文件中读取数据。但在后续章节学习了“管道和重定向”后,你将解锁更多强大的数据输入方式。

让我们开始吧!下面的例子只是这些命令功能的冰山一角,请务必发挥你的创造力,多多尝试。

为了方便演示,我们先创建一个名为 sales.txt 的示例文件,内容如下。你可以把它想象成一个简单的销售记录。

# 使用 cat 命令查看文件内容
$ cat sales.txt
张三 苹果 20
李四 橙子 5
王五 西瓜 12
赵六  4
孙七 橙子 9
周八 桃子 7
李四 橙子 12
王五 葡萄 39
吴九 芒果 7
郑十 菠萝 3
钱一 哈密瓜 2
冯二 青柠 14

head - 只看开头

head 命令就像它的名字一样,只显示文件或数据流的“头部”内容。默认情况下,它会显示前 10 行,但你可以通过参数指定行数。

语法: head [-n 行数] [文件路径]

示例1:默认显示前10行

$ head sales.txt
张三 苹果 20
李四 橙子 5
王五 西瓜 12
赵六  4
孙七 橙子 9
周八 桃子 7
李四 橙子 12
王五 葡萄 39
吴九 芒果 7
郑十 菠萝 3

示例2:指定只显示前4行

$ head -n 4 sales.txt
张三 苹果 20
李四 橙子 5
王五 西瓜 12
赵六  4

小提示: -n 4 也可以简写为 -4


tail - 只看结尾

tailhead 正好相反,它用于显示文件或数据流的“尾部”内容。默认也是显示最后 10 行。

语法: tail [-n 行数] [文件路径]

示例1:默认显示最后10行

$ tail sales.txt
王五 西瓜 12
赵六  4
孙七 橙子 9
周八 桃子 7
李四 橙子 12
王五 葡萄 39
吴九 芒果 7
郑十 菠萝 3
钱一 哈密瓜 2
冯二 青柠 14

示例2:指定只显示最后3行

$ tail -n 3 sales.txt
郑十 菠萝 3
钱一 哈密瓜 2
冯二 青柠 14

tail 还有一个非常有用的功能 tail -f,可以实时监控文件的新增内容,常用于查看日志文件。


sort - 排序

sort 命令用于对输入的数据进行排序。默认按字母(字典)顺序排序,但它有非常多的选项来控制排序规则。

语法: sort [选项] [文件路径]

示例:按默认规则排序

$ sort sales.txt
冯二 青柠 14
李四 橙子 12
李四 橙子 5
钱一 哈密瓜 2
孙七 橙子 9
王五 葡萄 39
王五 西瓜 12
吴九 芒果 7
张三 苹果 20
赵六  4
郑十 菠萝 3
周八 桃子 7

注意: sort 默认是按整行从第一个字符开始比较的。对于数字,"12" 会排在 "5" 的前面,因为它只看第一个字符 '1' 和 '5'。如果想按数值大小排序,可以使用 -n 选项。


nl - 添加行号

nl (Number Lines) 命令的功能很简单:为输入的每一行文本添加行号。

语法: nl [选项] [文件路径]

示例:添加默认行号

$ nl sales.txt
     1  张三 苹果 20
     2  李四 橙子 5
     3  王五 西瓜 12
     4  赵六  4
     5  孙七 橙子 9
     6  周八 桃子 7
     7  李四 橙子 12
     8  王五 葡萄 39
     9  吴九 芒果 7
    10  郑十 菠萝 3
    11  钱一 哈密瓜 2
    12  冯二 青柠 14

默认格式可能不是我们想要的,可以用选项来美化它。

示例2:自定义格式

$ nl -s '. ' -w 3 sales.txt
  1. 张三 苹果 20
  2. 李四 橙子 5
  3. 王五 西瓜 12
  4. 赵六  4
  5. 孙七 橙子 9
  6. 周八 桃子 7
  7. 李四 橙子 12
  8. 王五 葡萄 39
  9. 吴九 芒果 7
 10. 郑十 菠萝 3
 11. 钱一 哈密瓜 2
 12. 冯二 青柠 14
  • -s '. ':指定行号后面的分隔符为“点+空格”。因为包含了空格,我们用单引号 ' 把它包起来,告诉命令行这是一个整体。
  • -w 3:指定行号占用的宽度为3个字符。

wc - 统计计数

wc (Word Count) 不仅能统计单词,还能统计行数和字符数。

语法: wc [选项] [文件路径]

示例1:显示全部统计信息

$ wc sales.txt
 12  36 195 sales.txt

输出的三个数字依次代表:行数(12)、单词数(36)、字节数(195)

示例2:只统计行数

# -l 表示 lines
$ wc -l sales.txt
12 sales.txt

示例3:同时统计行数和单词数

# -w 表示 words
$ wc -lw sales.txt
 12  36 sales.txt

常用选项:-l (行数), -w (单词数), -c (字节数), -m (字符数)。


cut - 切分提取

如果你的数据是按列组织的(比如用空格、逗号或制表符分隔),cut 命令可以帮你精准地“切”出你想要的列。

语法: cut [选项] [文件路径]

我们的示例文件有3列:姓名、水果、数量。它们之间用空格分隔。

示例1:只提取第一列(姓名)

$ cut -d ' ' -f 1 sales.txt
张三
李四
王五
赵六
孙七
周八
李四
王五
吴九
郑十
钱一
冯二
  • -d ' ':指定分隔符(delimiter)为空格。cut 默认使用 Tab 键作为分隔符,所以当数据是其他分隔符时,必须用 -d 显式指定。
  • -f 1:指定提取第 1 个字段(field)。

示例2:提取第1列和第3列

$ cut -d ' ' -f 1,3 sales.txt
张三 20
李四 5
王五 12
赵六 4
孙七 9
周八 7
李四 12
王五 39
吴九 7
郑十 3
钱一 2
冯二 14

sed - 替换大师

sed (Stream Editor,流编辑器) 是一个极其强大的文本处理工具,最常见的用法就是进行查找和替换。

语法: sed 's/查找内容/替换内容/g' [文件路径]

这个表达式是 sed 的核心:

  • s:表示执行替换(substitute)操作。
  • 三个 /:是分隔符,用来划分“查找内容”和“替换内容”。
  • g:表示全局(global)替换,即替换行内的所有匹配项。如果省略 g,则只替换每行遇到的第一个匹配项。

示例:把所有的“橙子”都换成“香蕉”

$ sed 's/橙子/香蕉/g' sales.txt
张三 苹果 20
李四 香蕉 5
王五 西瓜 12
赵六  4
孙七 香蕉 9
周八 桃子 7
李四 香蕉 12
王五 葡萄 39
吴九 芒果 7
郑十 菠萝 3
钱一 哈密瓜 2
冯二 青柠 14

重要提示: sed 以及我们介绍的其他过滤器,默认情况下不会修改原始文件,它们只是把处理后的结果打印到屏幕上。这非常安全!如果你想保存结果,需要使用“重定向”技术,我们以后会学到。


uniq - 去除重复

uniq (Unique) 命令用于移除数据中连续的重复行。请注意“连续”这个关键词,这是 uniq 的一个重要特点。

语法: uniq [选项] [文件路径]

假设我们的 sales.txt 文件因为程序错误,产生了一些连续的重复记录:

# 新的 sales_with_duplicates.txt 文件
$ cat sales_with_duplicates.txt
张三 苹果 20
李四 橙子 5
李四 橙子 5
李四 橙子 5
王五 西瓜 12
赵六  4
王五 葡萄 39
王五 葡萄 39
吴九 芒果 7

示例:使用 uniq 去除重复

$ uniq sales_with_duplicates.txt
张三 苹果 20
李四 橙子 5
王五 西瓜 12
赵六  4
王五 葡萄 39
吴九 芒果 7

如果重复的行不相邻,uniq 是无法识别的。怎么办呢?聪明的你可能想到了:可以先用 sort 把文件排序,让所有重复的行都挨在一起,然后再用 uniq 处理!这就是命令组合的威力。


tac - 倒序输出

Linux 程序员有时候有点冷幽默。tac 这个命令就是 cat 的倒写,它的功能也和 cat 正好相反:它会从最后一行开始,反向逐行输出文件内容。

语法: tac [文件路径]

假设我们的销售记录是按时间顺序追加到文件末尾的,最新的记录在最下面。如果我们想让最新的记录显示在最上面,tac 就派上用场了。

示例:反向显示文件内容

$ tac sales.txt
冯二 青柠 14
钱一 哈密瓜 2
郑十 菠萝 3
吴九 芒果 7
王五 葡萄 39
李四 橙子 12
周八 桃子 7
孙七 橙子 9
赵六  4
王五 西瓜 12
李四 橙子 5
张三 苹果 20

进阶神器

除了上面介绍的这些,还有两个更强大的文本处理工具,它们几乎可以完成任何你想象得到的文本处理任务,但学习曲线也更陡峭一些。有兴趣的话可以自行探索:

  • grep: 强大的文本搜索工具,用于根据模式(正则表达式)查找行。
  • awk: 一种编程语言,专门用于处理和分析结构化文本(按列组织的数据)。

总结

  • head: 查看文件开头的若干行。
  • tail: 查看文件结尾的若干行。
  • sort: 对文本行进行排序。
  • nl: 为文本行添加行号。
  • wc: 统计行数、单词数和字符数。
  • cut: 按列切分并提取文本。
  • sed: 对文本进行查找和替换。
  • uniq: 移除连续的重复行。
  • tac: 反向输出整个文件。
  • 核心思想: 过滤器让我们能够像流水线一样处理数据,每个工具完成一个简单任务。
  • man 手册: 别忘了,man 是你最好的老师,可以查看命令的所有选项和用法。

动手练习

光说不练假把式,现在轮到你了!

  1. 仿照上面的例子,创建你自己的数据文件(比如一个班级的成绩单、购物清单等)。
  2. 对你的文件挨个使用上面介绍的所有命令,熟悉它们的基本功能。
  3. 为你感兴趣的命令(比如 sortcut)查阅 man 手册,尝试至少 2 个本文没有提到的命令行选项,看看它们会产生什么效果。

-- 感谢阅读 --