玩转 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
- 只看结尾
tail
与 head
正好相反,它用于显示文件或数据流的“尾部”内容。默认也是显示最后 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
是你最好的老师,可以查看命令的所有选项和用法。
动手练习
光说不练假把式,现在轮到你了!
- 仿照上面的例子,创建你自己的数据文件(比如一个班级的成绩单、购物清单等)。
- 对你的文件挨个使用上面介绍的所有命令,熟悉它们的基本功能。
- 为你感兴趣的命令(比如
sort
或cut
)查阅man
手册,尝试至少 2 个本文没有提到的命令行选项,看看它们会产生什么效果。