二、管道
1.管道
(1)是什么?
命令从 标准输入 到 读取数据,并将 数据 发送到 标准输出 的能力,是使用了名为 管道 的 shell特性。
(2)管道操作符“|”(怎么做)
使用管道操作符“|”,可把一个命令的 标准输出 传送到另一个命令的 标准输入 中。
① 用法格式
代码语言:javascript复制命令1 | 命令2
② 示例
代码语言:javascript复制less 命令可以分页显示任意命令的输入
ls -l /usr/bin | less
# 该命令将它的结果发送到标准输出,通过使用该技术,可以很方便地检查任意一条生成标准输出的命令 的运行结果。
2.过滤器
(1)是什么?
管道功能经常用来对数据执行复杂的操作。 也可以把多条命令合在一起构成一个管道。这种方式中用到的命令通常被称为过滤器。
(2)怎么做?
过滤器接受输入,按照某种方式对输入进行改变,然后再输出它。
① 示例
代码语言:javascript复制假设要把 /bin 和 /usr/bin 目录下的所有可执行程序合并成一个列表,并且按照顺序排列,最后再查看这个列表。
ls -l /bin /usr/bin | sort | less
# 指定了两个目录 /bin 和 /usr/bin ,ls的输出将包含两个排好序的列表,每个列表对应一个目录。
# 通过在管道中包含 sort 命令,将改变输出数据,从而产生一个排好序的列表。
3.uniq-报告或忽略文件中重复的行
uniq 命令经常和 sort 命令结合使用。 uniq 可以接受来自于 标准输入 或 一个单一文件名参数对应的已排好序的数据列表(可查看 uniq 的 man 页面)。
(1)删除所有重复行
默认情况下,该命令删除列表中的所有重复行。因此,在管道中添加 uniq 命令,可以确保所有的列表都没有重复行(重复行也就是在/bin 和 /usr/bin 目录下都出现相同名字的任意程序)。
① 示例
代码语言:javascript复制ls -l /bin /usr/bin | sort | uniq | less
# 使用了 uniq 命令来删除来自于 sort 命令输出内容中的任意重复行。
(2)查看重复行列表
代码语言:javascript复制想要查看重复行列表,可以在 uniq 命令后面添加 -d 选项。
ls -l /bin /usr/bin | sort | uniq -d | less
4.wc-打印行数、字数和字节数
wc 命令用来显示文件中包含的行数、字数和字节数。
(1)用法格式
代码语言:javascript复制wc [选项] 文件...
① 选项
-c 统计字节数。 -l 统计行数。 -m 统计字符数。这个标志不能与 -c 标志一起使用。 -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。 -L 打印最长行的长度。 -help 显示帮助信息 --version 显示版本信息
② 示例
代码语言:javascript复制wc ls-output.txt
# 显示ls-output.txt文件中所包含的行数、字数和字节数
(2)未输入参数
没有输入命令行参数,将接受标准输入内容。
(3)只打印行数
代码语言:javascript复制-l 选项限制命令只报告行数,把它添加到管道中可以很方便地实现计数功能。
ls /bin /usr/bin | sort | uniq | wc -l
# 查看已排序好的列表中的条目数
5.grep-打印匹配行
作用
用来在文件中查找匹配文本。
(1)用法格式
代码语言:javascript复制grep pattern [file...]
当 grep 在文件中遇到 “模式” 的时候,将打印出包含该模式的行。
① 示例
代码语言:javascript复制ls /bin /usr/bin | sort | uniq | grep zip
# 从列出的程序中搜索出文件名中包含 zip 的所有文件
(2)一对方便的选项
① -i:忽略大小写
该选项使得 grep 在搜索时忽略大小写(通常情况下,搜索是区分大小写的)。
② -v:输出和模式不匹配的行
该选项使得 grep 只输出和模式不匹配的行。
6.head/tail-打印文件的开头部分/结尾部分
有时,并不需要命令输出所有内容,可能只需要开头几行或者最后几行。 head 命令将输出文件的前 10 行。 tail 命令将输出文件的后 10 行。 默认情况下,这两条命令都是输出文件的 10 行内容,不过可以使用 -n 选项来调整输出的行数。
(1)head
① 用法格式
代码语言:javascript复制head [选项] file
② 示例
代码语言:javascript复制head ls-output.txt
# 显示 ls-output.txt 文件的前 10 行
head -n 5 ls-output.txt
# 显示 ls-output.txt 文件的前 5 行
ls /usr/bin | head
# 也可以应用在管道中
ls /usr/bin | head -n 5
(2)tail
① 用法格式
代码语言:javascript复制tail [选项] file
② 示例
代码语言:javascript复制tail ls-output.txt
# 显示 ls-output.txt 文件的后 10 行
tail -n 5 ls-output.txt
# 显示 ls-output.txt 文件的后 5 行
ls /usr/bin | tail
# 也可以应用在管道中
ls /usr/bin | tail -n 5
③ -f:实时查看文件
tail 中有一个选项用来实时查看文件,该选项在 观察正在被写入的日志文件的进展状态时很有用。 这个选项就是 -f ,tail 将持续监视这个文件,一旦添加了新行,新行将会立即显示在屏幕上。该动作在按下 Ctrl-C 后停止。
示例
代码语言:javascript复制观察 /var/log 目录下的 messages 文件(因为该文件可能包含安全信息,所以在一些 Linux 发行版中,需要超级用户的权限才能执行该操作)。
tail -f /var/log/messages
7.tee-从stdin读取数据,并同时输出到stdout和文件
为了和管道隐喻保持一致,Linux 提供了一个叫做 tee 的命令,就好像安装了一个 “T” 在管道上。 tee 命令读取标准输入,再把读到的内容复制到标准输出(允许数据继续向下传递到管道中)和 一个或多个文件中去。 当在某个中间处理阶段来捕获一个管道中的内容时,会很有用。 在执行Linux命令时,我们可以把输出重定向到文件中,比如 ls >a.txt,这时我们就不能看到输出了,如果我们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可以使用tee命令了。tee命令读取标准输入,把这些内容同时输出到标准输出和(多个)文件中。要注意的是:在使用管道线时,前一个命令的标准错误输出不会被tee读取。
(1)用法格式
代码语言:javascript复制tee
# 只输出到标准输出,因为没有指定文件嘛
tee file
# 输出到标准输出的同时,保存到文件file中。如果文件不存在,则创建;如果已经存在,则覆盖之
tee -a file
# 输出到标准输出的同时,追加到文件file中。如果文件不存在,则创建;如果已经存在,就在末尾追加内容,而不是覆盖
tee -
# 输出到标准输出两次
tee file1 file2 -
# 输出到标准输出两次,同时保存到file1和file2中
示例
代码语言:javascript复制ls /usr/bin | tee ls.txt | grep zip
# 在使用 grep 命令过滤管道内容之前,先使用 tee 命令来获取整个目录列表并输出到 ls.txt 文件中。