awk读取标准输入的讨论&awk源码读取输入部分分析

来源:互联网 发布:人机界面触摸屏软件 编辑:程序博客网 时间:2024/05/14 21:54

今天群里有人问了个问题:

grep ...|awk ... filename
这种情况下awk先将管道|的数据处理完后,再开始处理文件filename么?

 

答案很多人都知道是否定的,

一般的格式是:grep ...filename|awk ...

不过问题目的人是想实现这样的功能:

grep ... file1 | awk ... file2

将grep后的结果送给awk先存下来,再处理file2

大致的需求是明白了

问题大于awk在有文件参数的情况下是忽视标准输入的(见下边的源码分析)

所以解决的方法有下边几个

1:awk ...  <(grep ... file1)    file2

2:grep ... file1 | awk ...  -  file2

 

 

下边是关于awk源码读取输入的分析:

 

main函数在进行参数,初始化后,调用do_input()读取输入

Do_input使用while循环,处理“每个输入”

 while ((iop = nextfile(FALSE)) != NULL) {}

其中nextfile函数调用iop_open打开文件

Iop_open函数里有么一段:

        if (STREQ(name, "-"))                                                                                    

                openfd = fileno(stdin);                                                                          

        else if (do_traditional)                                                                                 

                goto strictopen;  

strictopen:                                                                                                      

        if (openfd == INVALID_HANDLE)                                                                            

                openfd = open(name, flag, 0666); 

即对待-,是去读取输入的

 

 

再回头来看看参数解析过程,

main函数里进行解析输入文件参数:       srcfiles_add(CMDLINE, argv[optind]); 

 

实际上是个宏定义:

 

#define srcfiles_add(stype, val) /

        add_src(&srcfiles, &numfiles, &allocfiles, stype, val)

 

往一个数据结构里去增加一个元素,一个元素代表一个输入文件

并上上述的next_file中去遍历

        static long i = 1;//初始i1

  static int files = FALSE;

     for (; i < (long) (ARGC_node->lnode->numbr); i++) {

                        files = TRUE;}// ..里调用lookup去查找文件,找到时,files会置为true

 

        if (files == FALSE) {

                files = TRUE;

                /* no args. -- use stdin */

                /* FNR is init'ed to 0 */

 

根据filesfalse判断无输入文件参数(包括-),即默认读取stdin做为输入

 

结论:

 

Awk:读取输入的几种方式

1:没有指定输入文件,即读取标准输入(通常采用管道实现)

2:有输入文件,就不读取标准输入(除非指定-)

3:如果有输入文件,又想读取标准输入,可以用-,即为开头的例子