第六章: 重定向
本章介绍IO重定向和管道, 以及以下命令的使用:
- cat: 合并文件
- sort: 对文本行排序
- uniq: 报告或删除文件中重复行
- wc: 打印文件中的换行符, 字和字节的个数
- grep: 打印匹配行
- head: 输出文件的第一部分
- tail: 输出文件的最后一部分
- tee: 读取标准输入的数据并将其内容输出到标准输出和文件中
6.1 标准输入, 标准输出和标准错误
类似ls的程序实际上把它们的运行结果发送到称为标准输出的文件中, 状态信息发送到称为标准错误的文件中. 默认情况下标准输出和标准错误都将被链接到屏幕上, 并且不会保存到磁盘文件中.
另外许多程序从标准输入的设备来得到输入, 默认情况下标准输入链接到键盘.
IO重定向功能可以改变输出内容发送的目的地, 也可以改变输入内容的来源地.
6.1.1 标准输出重定向
使用重定向操作符 [>] 后面接文件名, 可以把标准输出重定向到另一个文件中.
ls -l /usr/bin > ls-output.txt
使用重定向操作符 [>] 来重定向标准输出时, 目的文件通常会从文件开头部分重新改写. 所以可以通过以下方式创建空文件或删除文件内容:
> ls-output.txt
使用重定向操作符 [>>] 可以将输出内容添加到文件尾部, 如果文件不存在也将创建文件.
6.1.2 标准错误重定向
标准错误的重定向并不能通过简单的使用一个专门的重定向符来实现, 而是要通过文件描述符. shell内部用描述符索引0, 1, 2 来代表标准输入文件, 标准输出文件和标准错误文件. 所以可以通过以下命令重定向标准错误:
ls -l /bin/usr 2> ls-error.txt
6.1.3 将标准输出和标准错误重定向到同一个文件
传统上可以通过以下命令重定向标准输出和标准错误到同一个文件:
ls -l /usr/bin > ls-output.txt 2>&1
即先将标准输出重定向到ls-output.txt, 然后把标准错误重定向到文件描述符1中. 注意不能调整为以下命令:
ls -l /usr/bin 2>&1>ls-output.txt
以上命令标准错误将被重定向到屏幕而不是文件, 因为标准错误重定向是标准输出还没有重定向, 还是链接到屏幕的.
在最近的bash中提供了以下的写法:
ls -l /usr/bin &> ls-output.txt
标记符 [&>] 可以把标准输出和标准错误重定向到一个文件中.
6.1.4 处理不想要的输出
如果想要忽略输出, 可以使用以下命令:
ls -l /usr/bin 2> /dev/null
6.1.5 标准输入重定向
cat命令读取一个或多个文件, 并把它们复制到标准输出文件中, 格式如下:
cat [file...]
假设有一个大文件被拆分为多个文件, 名字依次为 movie.mpeg.001, movie.mpeg.002 .. movie.mpeg.099, 现在使用cat命令把它们重新连接起来:
cat movie.mpeg.0* > movie.mpeg
如果cat命令没有指定任何参数, 它将从标准输入读取内容, 输入内容后按下 Ctrl+D, 告知cat命令它已经达到了标准输入的文件尾(end-of-file, EOF).
我们也可以使用重定向符 [<] 把标准输入重定向到文件:
cat < lazy_dog.txt
6.2 管道
命令从标准输入到读取数据, 并把数据发送到标准输出的能力, 是使用了名为管道的shell特性. 使用管道操作符 [|] 可以把一个命令的标准输出传送到另一个命令的标准输入中.
# command1 | command2
# 例如
ls -l /usr/bin | less
6.2.1 过滤器
管道功能经常用来对数据执行复杂的操作, 也可以把多条命令合在一起构成一个管道, 这种方式中用到的命令通常称为过滤器. 过滤器接受输入, 按照某种方式对输入进行改变, 然后再输出它.
例如把两个目录下的所有可执行程序合并成一个列表, 并且按照顺序排列, 最后再查看这个列表.
ls /bin /usr/bin | sort | less
6.2.2 uniq-报告或忽略文件中重复的行
uniq可以接受来自于标准输入或一个单一文件名参数对应的已经排序好的数据列表, 默认情况下该命令删除列表中的所有重复行, -d参数可以查看重复的行.
ls /bin /usr/bin | sort | uniq | less
6.2.3 wc-打印行数, 字数和字节数
wc命令用来显示文件中包含的行数, 字数和字节数. wc在没有输入行参数时将从标准输入获取数据, -l选项参数限制命令只统计行数.
ls /bin /usr/bin | sort | uniq | wc
6.2.4 grep-打印匹配行
grep是一个强大的程序, 用来从文件中查找匹配的文本, 使用方式如下:
grep pattern [file...]
假设我们需要从列出的程序中找出文件名包含zip的行:
ls /bin /usr/bin | sort | uniq | grep zip
6.2.5 head/tail-打印文件开头/结尾部分
head命令输出文件的前10行, tail输出文件的最后10行. 可以使用 -n 参数来调整输出的行数.
ls /usr/bin | tail -n 5
6.2.6 tee-从stdin读取数据, 并同时输出到stdout和文件
tee命令读取标准输入, 再把读到的内容复制到标准输出和一个或更多的文件中去.
ls /usr/bin | tee ls.txt | grep zip
以上的命令在把目录列表输出到grep过滤之前, 利用tee命令将内容写入到文件中.