找回密码
 注册
查看: 1985|回复: 4

问个awk的循环问题

[复制链接]
发表于 2011-11-14 17:28:28 | 显示全部楼层 |阅读模式
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退出。请各位高手分析下症结所在。如果要实现上面的目的,请问该怎么写代码
发表于 2011-11-15 08:47:48 | 显示全部楼层
不懂awk,不过从循环来看,i=0不应该放在那里吧,那样i一直会是0的。当然会死循环了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-11-15 09:24:12 | 显示全部楼层
i是循环控制变量,先在while循环体外初始化为i=0,然后循环条件为 i<max_records,在循环体内,每找到一个符合条件的行,就将 i 加1,这样找到max_records个符合条件的项后,就退出循环。

看上去感觉没有问题啊。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-11-15 17:07:01 | 显示全部楼层
实验了半天,终于找到解决方法了,原来要把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
回复 支持 反对

使用道具 举报

发表于 2011-11-15 17:55:42 | 显示全部楼层
用循环应该也行吧,不过i的位置的确不应该在那里,那里的话,你仔细考虑下,i的值会一直是0的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2022-8-17 23:36 , Processed in 0.098040 second(s), 15 queries .

© 2021 Powered by Discuz! X3.4.

快速回复 返回顶部 返回列表