请教关于如何判断awk状态,退出循环的问题
大家好~!
有如下脚本:
#!/bin/bash
#for line in $(<$1);
cat $1 | while read line
#while read line
do
# echo ${line}
# print AIX version like 5.3.9.1
echo $line | awk -F',' '/AAA,AIX/ { print $3 }'
# print report date ,like 15-APR-2011
echo $line | awk -F',' '/AAA,date,/ { print $3 }'
# print report time ,like 16:36:49
echo $line | awk -F',' '/^AAA,time,/ { print $3 }'
#done < $1
done
这个脚本,基本意思是:
从$1接收一个文件,每次读取一行的内容,然后用awk来过滤这一行,碰到匹配的,就打印$3列。
现在的问题是,这个脚本,会将读取的每一行都与下面所有的awk语句来匹配,即使在第1行,已经匹配到了合适的条件了,也要继续匹配剩下的所有awk行。这样的话,很浪费系统资源。
我想请教大家,如何做?使得awk一旦匹配出了合适的行,就退出while循环,再来读取下一行做匹配?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
本帖最后由 yinyuemi 于 2011-04-18 13:19 编辑
加exit;
例如:
awk -F',' '/AAA,date,/ { print $3 ;exit}'
谢谢你的回复。不过好像没有退出阿~!
#!/bin/bash
#for line in $(<$1);
cat $1 | while read line
#while read line
do
# echo ${line}
# print AIX version like 5.3.9.1
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
# print report date ,like 15-APR-2011
echo $line | awk -F',' '/^AAA,date,/ { print $3;exit }'
# print report time ,like 16:36:49
echo $line | awk -F',' '/^AAA,time,/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
#done < $1
done
[root@vistor itools]# time ./test.sh Orasvr_110418_1110.nmon
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
6.1.6.1
11:10:19
18-APR-2011
real 0m28.805s
user 0m4.199s
sys 0m9.883s
我加了几行到里面,然后一跑,发现每读取一行,还是把所有后面的awk判断语句都做了比对,从结果中就可以看出,打印了很多重复的行。
回复 3# donggua0713
sorry,开始没大看清你的意思
我觉得你可以试试这样:
cat $1 |awk -F ',' '
/^AAA,AIX/ { print $3 }
/AAA,date,/ { print $3}
/AAA,time,/ { print $3;exit }'
目前我的测试文件有1300多行,不排除有2万多,3万行的文件。而且这样的文件可能有N×100个,所以效率很成问题。现在看来,可能shell不能胜任这样的工作。
这样不行的,还是在最后一个awk语句之后退出,我希望一旦匹配到,就退出,比如:
# print AIX version like 5.3.9.1
echo $line | awk -F',' '/^AAA,AIX/ { print $3;exit }'
当读到一行内容是AAA,AIX,abcdef的时候,打印abcdef,然后退出当前while循环,就不继续对比下一个awk语句了。
本帖最后由 donggua0713 于 2011-04-18 13:29 编辑
还有个问题,大家看到我的脚本,注释掉了for循环的语句。因为我测试过,其他语句都相同,使用for循环,和使用while循环,性能差异巨大。for循环耗费的时间,是while循环的6倍。
不知道大家还有什么好的办法,提高循环的效率?
我这个脚本,肯定写得不好,所以跑一次测试脚本,1300行,3个判断条件,要6秒左右。
回复 7# donggua0713
如果是匹配任意一个就退出的话:
cat $1 |awk -F ',' '
/^AAA,AIX/ || /AAA,date,/ || /AAA,time,/ { print $3;exit }'
如果我 awk前面的匹配部分,有上百个条件,这样写很痛苦阿