中国Linux公社论坛's Archiver

voodoomaster 发表于 2011-11-14 17:28

问个awk的循环问题

shell代码:

    awk -v max_records=50 '
        BEGIN { FS="|" }
        {
            i=0;
            while (i < max_records)
                {
                    if(($1 >= 10) && ($2 <= 20))
                        {
                            i++;
                            print NR,$1,$2;
                        }
                }
        }
        END {}' \
        test.txt

编程目的:text文件的域分割符为“|”,在其中查找第1域值大于10且第2域值小于20的行,只需要找到满足条件的前50行并将其打印出来即可,后面的都忽略

由于文件非常巨大,满足条件的行有几万行,考虑到脚本的执行效率问题,设置了一个变量max_records,只需要awk程序查找满足条件的前max_records行即退出,不需要查找后面的行了。

运行以上程序,死循环,只有Ctrl + C退出。请各位高手分析下症结所在。如果要实现上面的目的,请问该怎么写代码

sejishikong 发表于 2011-11-15 08:47

不懂awk,不过从循环来看,i=0不应该放在那里吧,那样i一直会是0的。当然会死循环了。

voodoomaster 发表于 2011-11-15 09:24

i是循环控制变量,先在while循环体外初始化为i=0,然后循环条件为 i<max_records,在循环体内,每找到一个符合条件的行,就将 i 加1,这样找到max_records个符合条件的项后,就退出循环。

看上去感觉没有问题啊。

voodoomaster 发表于 2011-11-15 17:07

实验了半天,终于找到解决方法了,原来要把i=0放在BEGIN字段里面,而且要用if...else的判断结构,不是用循环

awk -v max_records=50 '
BEGIN { FS="|"; i=0}
{
  if((i < max_records)
     {
        if($1 >= 10) && ($2 <= 20))
          {
             i++;
             print NR,$1,$2;
          }
     }
  else
    {
       exit;
    }
}
END {}' \
test.txt

sejishikong 发表于 2011-11-15 17:55

用循环应该也行吧,不过i的位置的确不应该在那里,那里的话,你仔细考虑下,i的值会一直是0的。

页: [1]

Powered by Discuz! Archiver 6.1.0F  © 2001-2007 Comsenz Inc.