一个“过滤器”程序就是一个从标准输入流(
stdin
)读取数据并写入标准输出流(
stdout
)的程序。在写入读取的数据之前,通常会以某种方式进行转换(如果你不进行任何转换或过滤,则基本上编写了一个
cat
程序,它只打印出给定的内容)。过滤器程序的强大之处在于它们不指定其输入来自何处或输出将去向何方。相反,由调用程序提供输入/输出通道。
过滤器程序的核心可能看起来像这样(您可以将其用作自己的过滤器程序的模板):
#include <stdio.h>
int filter( FILE *input, FILE *output );
int main( void )
{
const int retval = filter( stdin, stdout );
fflush( stdout );
return retval;
}
就是这样。实际的工作是由一个 filter
函数完成的,该函数执行所需的转换。例如,这里有一个简单的程序,它从输入文件中读取字符,将它们转换为小写字母,然后将它们打印到输出文件中:
#include <stdio.h>
#include <ctype.h>
int filter( FILE *input, FILE *output )
{
while ( !feof( input ) ) {
if ( ferror( input ) ) {
return 1;
}
fputc( tolower( fgetc( input ) ), output );
}
return 0;
}
int main( void )
{
const int retval = filter( stdin, stdout );
fflush( stdout );
return retval;
}
如果您编译并运行此程序,它将只是静静地等待从标准输入文件
stdin
读取数据。该文件通常绑定到控制台,这意味着您必须手动输入一些数据。但是,命令 shell 实现了一种名为管道的特性,允许您将一个命令的输出导入到另一个命令的输入中。这使得可以将多个程序组合成一个
pipeline 来形成强大的命令。
以下是如何使用我们的过滤程序(假设您将结果二进制文件称为
lower
):
$ echo Hello | lower
hello
$
由于我们的过滤程序没有定义要读取的数据来自哪里,因此我们可以将其与所有在标准输出上产生输出的程序结合使用。例如,以下是如何将整个文件转换为小写(在 Windows 机器上可以使用
type
):
$ cat myfile.txt
Hello, World!
This is a simple test.
$ cat myfile.txt | lower
hello, world!
this is a simple test.
$