Skip to content

Unix / Linux - 管道与过滤器

Unix 哲学中最强大的概念之一是组合简单、专业的工具来执行复杂任务。管道和过滤器是实现这一方法的核心。

管道,用竖线字符 (|) 表示,将一个命令的标准输出 (stdout) 连接到下一个命令的标准输入 (stdin)。这使得数据可以按顺序流经一连串命令。

过滤器是一个设计用于从标准输入接收输入,以某种方式处理它(例如,选择行、排序数据、转换文本),并将结果写入标准输出的命令。许多标准的 Unix 工具可以作为过滤器。

command1 | command2 | command3

在这个例子中,command1 的输出成为 command2 的输入,而 command2 的输出成为 command3 的输入。最终输出会显示在终端上(或者可以被重定向)。

grep (Global Regular Expression Print) 是一个基础的过滤器,用于在输入文本(来自标准输入或文件)中搜索包含特定模式的行。

语法:

$ grep [options] pattern [file(s)]
# 或者使用标准输入:
$ command | grep [options] pattern

模式可以是简单的字符串,也可以是更复杂的正则表达式。

示例:使用 ls -l 和 grep 仅列出当前路径中的目录。

# ls -l 列出文件和目录
# grep '^d' 过滤出以 'd' 开头的行(目录)
$ ls -l | grep '^d'
drwxr-xr-x 2 user group 4096 Jul 25 15:30 documents
drwxr-xr-x 4 user group 4096 Jul 25 15:35 project
drwxr-xr-x 2 user group 4096 Jul 25 15:28 tmp

常用 grep 选项:

选项描述
tds
tds
tds
tds
tds
tds
tds
tds
tds

示例:在日志文件中查找包含 ‘error’(不区分大小写)的行:

$ grep -i 'error' /var/log/app.log /var/log/syslog

示例:统计用户 ‘alice’ 登录的次数(使用 who 命令输出):

$ who | grep '^alice ' | wc -l

sort 命令按字母或数字顺序排列文本行。

# colors.txt 的内容:
# blue
# red
# green
# yellow
$ sort colors.txt
blue
green
red
yellow

常用 sort 选项:

选项描述
tds
tds
tds
tds
tds
tds
tds

示例:列出文件,按大小(第 5 个字段,数字排序)排序,最大在前。

# ls -l 输出:权限 链接数 用户组 用户 大小 日期 名称
# 我们希望按第 5 个字段(大小)进行数字排序 (-n) 并反转顺序 (-r)
$ ls -l | sort -k 5nr
-rw------- 1 user group 1048576 Jul 25 16:00 large_file.dat
-rw-r--r-- 1 user group 51200 Jul 25 15:55 medium_data.bin
drwxr-xr-x 5 user group 4096 Jul 25 15:35 project
-rw-r--r-- 1 user group 1024 Jul 25 16:01 small_config.txt
...

示例:按第 2 个字段(逗号分隔)对 CSV 文件进行排序。

$ sort -t ',' -k 2 data.csv

uniq 命令过滤掉已排序输入流中相邻的重复行。输入必须先经过排序,这一点至关重要。

# items.txt 的内容:
# apple
# banana
# apple
# orange
# banana
# 先排序,然后找到唯一项
$ sort items.txt | uniq
apple
banana
orange

常用 uniq 选项:

  • -c: 在每行前加上出现次数。
  • -d: 仅打印重复行(每组一行)。
  • -u: 仅打印唯一行(不重复的行)。

示例:统计每个项的出现次数。

$ sort items.txt | uniq -c
2 apple
2 banana
1 orange

当命令或管道的输出过长,无法在一屏显示时,可以通过管道将其传递给分页器,如 less。less 允许你上下滚动、搜索,并逐屏查看输出。

通常更推荐使用 less,因为它比旧的 more 命令更容易向后滚动。

# 逐页查看长进程列表
$ ps aux | less
# 列出所有文件,按大小排序,逐页查看
$ ls -l /usr/bin | sort -k 5nr | less

在 less 中,使用箭头键、PageUp/Down 进行导航,/ 向前搜索,? 向后搜索,q 退出。

真正的强大之处在于将多个过滤器链式组合起来。

示例:在 Web 服务器日志文件 (access.log) 中查找出现次数最多的前 5 个 IP 地址。假设 IP 是第一个字段。

# 1. 使用 cut 提取第一个字段(IP 地址)
# 2. 按字母顺序排序 IP
# 3. 统计相邻的重复项(使用 uniq -c)
# 4. 按数字顺序排序计数,最大在前(sort -nr)
# 5. 取前 5 行(head -n 5)
$ cut -d ' ' -f 1 access.log | sort | uniq -c | sort -nr | head -n 5
1532 192.168.1.101
987 10.0.0.5
750 172.16.30.2
610 192.168.1.150
405 10.0.0.8

其他有用的过滤器包括 cut(从行中提取部分)、tr(转换或删除字符)、sed(流编辑器,用于文本转换)和 awk(强大的模式扫描和处理语言)。探索这些工具可以解锁高级文本处理能力。