shell提供了数种语法标记,可用来改变默认I/O的来源端与目的端。我们先介绍基本用法。
以<改变标准输入
program < file 可将program的标准输入修改为file:
tr -d '\r' < dos-file.txt ...
tr命令用法
以>改变标准输出
program > file 可将program的标准输出修改为file:
tr -d '\r' < dos-file.txt > UNIX-file.txt
这条命令会先以tr将dos-file.txt里的'\r'删除,再将转换完成的数据输出到UNIX-file.txt。dos-file.txt里的原始数据不会有变化。
>重定向符(redirector)在目的文件不存在时,会新建一个。然而,如果目的文件已存在,它就会被覆盖掉,原本的数据都会丢失。
以>>附加到文件
program >> file 可将program 的标准输出附加到file的结尾处。
如同>,如果目的文件不存在,>>重定向符便会新建一个。然而,如果目的文件存在,它不会直接覆盖掉文件,而是将程序所产生的数据附加到文件结尾处:
for f in dos-file.txt
do
tr -d '\r' < $f >> big-UNIX-file.txt
done
以|建立管道
program1 | program2可将program1的标准输出修改为program2的标准输入
虽然<与>可将输入与输出连接到文件,不过管道(pipeline)可以把两个以上执行中的程序衔接在一起。第一个程序的标准输出可以变成第二个程序的标准输入。这么做的好处是,管道可以使得执行速度比使用临时文件的程序快上十倍左右
tr -d '\r' < dos-file.txt | sort > UNIX-file.txt
这条管道会先删除输入文件内的回车字符,在完成数据的排序之后,将结果输出到目的文件。
使用UNIX工具程序时,不妨将数据想象成水管里的水,未经处理的水,将流向净水厂,经过各类滤器的处理,最后产生适合人类引用的水。
同样,编写脚本时,通常已有某种输入格式定义下的原始数据,而需要处理这些数据后产生结果。(处理一次表示很多意思,例如排序、加和与平均、格式化以便于打印等等)从原始数据开始,然后构造一条管道,一步一步地,管道中的每个阶段都会让数据更接近想要的结果。
对于我们UNIX新手,可以把<与>想象成数据的漏斗(funnels)--数据会从大的一端进入,由小的一端出来。
注意:构造管道时,应该试着让每个阶段的数据量变得更少。换句话说,如果你有两个要完成的步骤与先后次序无关,你可以把会让数据变少的那一个步骤放在管道前面。这么做可以提升脚本的整体性能,因为UNIX只需要在两个程序间移动少的数据量,每个程序要做的事也比较少。
例如,在使用sort排序之前,先以grep找出相关的行;这样可以让sort少做些事。