免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3485 | 回复: 11

[文本处理] [已解决]检查“重复”启动的process,uniq搞不定了,awk怎么写 [复制链接]

论坛徽章:
0
发表于 2012-10-01 15:47 |显示全部楼层
本帖最后由 可可火山 于 2012-10-03 16:21 编辑

本来有个脚本去检查是否有重复的程序运行着,开始使用 ps 在awk取用户和命令部分 然后sort再uniq -d.
不过该程序支持-s 指定开始处理的number,这样其实加-s 参数和不加的程序认为是相同的。 -c 是指定配置文件,所以配置文件不同可以认为不同的程序。

下面的output为例子
user runapp -c 2runappconf1.cfg
user runapp -c 2runappconf1b.cfg -s 10030
user runapp -c 2runappconf1c.cfg
user runapp -c 2runappconf1c.cfg

user runapp -c 2runappconf2.cfg -s 10405
user runapp -c 2runappconf2b.cfg -s 9951
user runapp -c 2runappconf2c.cfg -s 10177
user runapp -c 2runappconf3.cfg -s 10406
user runapp -c 2runappconf3b.cfg -s 9892
user runapp -c 2runappconf3c.cfg -s 19662
user runapp -c 2runappconf4.cfg -s 10372
user runapp -c 2runappconf4b.cfg -s 9939
user runapp -c 2runappconf4c.cfg -s 9798
user runapp -c 2runappconf5.cfg -s 10604
user runapp -c 2runappconf5b.cfg -s 10043
user runapp -c 2runappconf5c.cfg -s 9907
user runapp -c 2runappconf6.cfg
user runapp -c 2runappconf6.cfg -s 9999

user runapp -c 2runappconf7.cfg -s 1173752


user runapp -c 2runappconf1c.cfg
通过sort 再uniq -d 可以找出来,但是
user runapp -c 2runappconf6.cfg
user runapp -c 2runappconf6.cfg -s 9999
应该是重复的进程,sort+uniq已经不可以把这两行找出来了。所以准备写awk脚本。

先考虑简单的情况,也就是上面的例子。
{
if(PRELINE==$0){
print $0;
}
if($0 ~ /PRELINE -s [0-9]*/){
print PRELINE "\n" $0;
}
PRELINE=$0
}

其中当上一行和当前行相同时,打印当前行,就是uniq -d的输出 (暂不说output有重复多行的话先不考虑)
当前行匹配上一行加 -s 数字参数的话也认为是重复,同时打印当前行和下一行。 不过好像语法什么的不同,或者正则内部不能用变量?这部分脚本好像不工作。
请教下大家, 谢先。

update 20121003 写了个比较胖的版本。应该还能再简化点。脚本:


具体测试和结果请看后面回复。
  1. {
  2.     TMP=$0;
  3.     gsub(" -s [0-9]*","",TMP);
  4.     CURLINEKEY=TMP;
  5.     if(PRELINE==$0&&PREPRELINE!=$0)print $0;
  6.     if(PRELINE!=$0&&CURLINEKEY==PRELINEKEY){
  7.         if(PREPRELINEKEY!=PRELINEKEY){
  8.             print PRELINE;
  9.         }
  10.             print $0;
  11.     }

  12.     PREPRELINE=PRELINE;
  13.     PREPRELINEKEY=PRELINEKEY;
  14.     PRELINE=$0;
  15.     PRELINEKEY=CURLINEKEY;
  16. }
复制代码

论坛徽章:
0
发表于 2012-10-01 18:08 |显示全部楼层
本帖最后由 可可火山 于 2012-10-01 18:13 编辑

看了下 awk FAQ http://awk.freeshell.org/Frequently_Asked_Questions
正则中用变量需要显示并且不要 /***/括起来。
5. How do I use a variable as a regular expression?

The patterns between slashes like /pattern/ are called ERE constants, or regular expressions literals. As the names imply, they can only contain fixed, constant regular expressions. If you have a variable var that contains "abc(123)?r+" and try to match something against /var/, you are matching against the literal string "var", not against the regular expression. You can still use strings in places where regular expressions are expected, like this:

var="abc(123)?r+"
if ($1 ~ var){ # $1 matches, do something }

or

BEGIN{var="abc(123)?r+"}
$0 ~ var { # $0 matches, do something }

Also note that when you're using a string as a regular expression you must explicitly match it against the string you want to check; you can NOT use the string alone and expect awk to understand that you mean $0 ~ string, as happens instead for RE literals. Finally, using a string as a regex produces what's called a "computed" or "dynamic" regex. For a detailed discussion of computed regexes and the issues you should be aware of when using them, see the GNU awk manual.



我改了下脚本,基本满足要求,
  1. {
  2. if(PRELINE==$0){
  3. print $0;
  4. }
  5. if($0 ~ REGEXRULE && NR>1 ){
  6. print PRELINE "\n" $0;
  7. }
  8. PRELINE=$0;
  9. REGEXRULE=$0" -s [0-9]*";
  10. }
复制代码
接下去就是让脚本更强壮些,
如果同名重复的脚本超过2个。
比如带-s参数的相同脚本带起了2个以上。


论坛徽章:
5
未羊
日期:2014-08-04 16:15:21天秤座
日期:2014-08-13 13:52:372015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:112015亚冠之浦和红钻
日期:2015-06-29 15:30:48
发表于 2012-10-01 18:55 |显示全部楼层
  1. awk '!a[$3,$NF]++'
复制代码

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
发表于 2012-10-01 19:29 |显示全部楼层
  1. awk 'NR==FNR{a[$2,$4]++;next} a[$2,$4]>1'  output output
复制代码

论坛徽章:
0
发表于 2012-10-01 19:57 |显示全部楼层

  1. awk '{if(c!=$4)c=$4;else if(a){print a;print $0};a=$0}' file
复制代码

论坛徽章:
0
发表于 2012-10-01 20:28 |显示全部楼层
谢谢大家都热心,不过我现在主要是要能判断 当前运行的重复程序,
1) 命令行完全相同
2)使用相同配置文件-c ,有指定 -s 数字参数或没指定为相同并输出。

不同的不需要输出。

输入例子其实是 user + command
user runapp -c 2runappconf6.cfg
user runapp -c 2runappconf6.cfg -s 9999

大家提供了不少方案,需要点时间消化,不过好像都没看到对 -s 数字的处理。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
发表于 2012-10-02 00:54 |显示全部楼层
回复 6# 可可火山


    看起来,你的要求是不是可以理解为:只要“使用相同配置文件-c”相同即可,因为不管是否有-s,前面的都是一样的

论坛徽章:
0
发表于 2012-10-02 08:27 |显示全部楼层
本帖最后由 可可火山 于 2012-10-02 08:30 编辑

回复 7# yinyuemi

是的

目前自己折腾的长长的awk脚本基本功能已经满足需求,现在是要多考虑些场景。
  1. /usr/xpg4/bin/awk '{if(PRELINE==$0) print $0;if($0 ~ REGEXRULE && NR > 1)print PRELINE "\n" $0;PRELINE=$0;REGEXRULE=$0" -s [0-9]*";}'
复制代码
(solaris默认/usr/bin/awk好像有些功能不支持)

1) 相同的命令启动了超过2个,比如有n个相同程序运行着,我的脚本会输出n-1个
2) 脚本目前还只能处理一个相同配置并且另外一个是-s,如果再第三个程序也是相同配置文件并带个-s的话就不能输出。

如下面的例子
user runapp -c 2runappconf1.cfg
user runapp -c 2runappconf1b.cfg -s 10030
user runapp -c 2runappconf1c.cfg
user runapp -c 2runappconf1c.cfg
user runapp -c 2runappconf1c.cfg

user runapp -c 2runappconf2.cfg -s 10405
user runapp -c 2runappconf2b.cfg -s 9951
user runapp -c 2runappconf2c.cfg -s 10177
user runapp -c 2runappconf3.cfg -s 10406
user runapp -c 2runappconf3b.cfg -s 9892
user runapp -c 2runappconf3c.cfg -s 19662
user runapp -c 2runappconf4.cfg -s 10372
user runapp -c 2runappconf4b.cfg -s 9939
user runapp -c 2runappconf4c.cfg -s 9798
user runapp -c 2runappconf5.cfg -s 10604
user runapp -c 2runappconf5b.cfg -s 10043
user runapp -c 2runappconf5c.cfg -s 9907
user runapp -c 2runappconf6.cfg
user runapp -c 2runappconf6.cfg -s 8888
user runapp -c 2runappconf6.cfg -s 9999

user runapp -c 2runappconf7.cfg -s 1173752
脚本输出
  1. user runapp -c 2runappconf1c.cfg
  2. user runapp -c 2runappconf1c.cfg
  3. user runapp -c 2runappconf6.cfg
  4. user runapp -c 2runappconf6.cfg -s 8888
复制代码
希望输出是
  1. user runapp -c 2runappconf1c.cfg
  2. user runapp -c 2runappconf6.cfg
  3. user runapp -c 2runappconf6.cfg -s 8888
  4. user runapp -c 2runappconf6.cfg -s 999
复制代码

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
发表于 2012-10-02 09:45 |显示全部楼层
回复 8# 可可火山

try
  1. awk '{if(n==$4){if(!m)print t;if(/-s/)print;m=1}else{m=0};n=$4;t=$0}'
复制代码

论坛徽章:
0
发表于 2012-10-03 16:18 |显示全部楼层
回复 9# yinyuemi


    谢谢热心,最近国庆加班忙着做其他事情,可能有些需求也没讲清楚。
自己又折腾了下,功能是实现了,脚本比较丑,判断的时候引入了当前行CURLINE,前面一行PRELINE和前面的前面一行PREPRELINE,以及gsub去掉-s number作为判断的KEY。

需求:
检查系统当前运行重复的程序,程序可以是不同,可以运行在不同用户下。原来脚本的做法是ps出来然后awk print出用户+CMD.
然后对结果做一次sort和uniq-d 来得到重复的。不过问题是uniq不能判断相同用户下,配置文件相同但有-s参数不同。

最终版本脚本:
  1. {
  2.     TMP=$0;
  3.     gsub(" -s [0-9]*","",TMP);
  4.     CURLINEKEY=TMP;
  5.     if(PRELINE==$0&&PREPRELINE!=$0)print $0;
  6.     if(PRELINE!=$0&&CURLINEKEY==PRELINEKEY){
  7.         if(PREPRELINEKEY!=PRELINEKEY){
  8.             print PRELINE;
  9.         }
  10.             print $0;
  11.     }

  12.     PREPRELINE=PRELINE;
  13.     PREPRELINEKEY=PRELINEKEY;
  14.     PRELINE=$0;
  15.     PRELINEKEY=CURLINEKEY;
  16. }
复制代码
[appuser@dupprocess (0)]$cat ps.out
user runapp -c 2runappconf1.cfg
user runapp -c 2runappconf1.cfg
user runapp -c 2runappconf1.cfg
user runapp -c 2runappconf1b.cfg -s 10030
user runapp -c 2runappconf1c.cfg
user runapp -c 2runappconf1c.cfg
user runapp -c 2runappconf2.cfg -s 10405
user runapp -c 2runappconf2.cfg -s 10444
user runapp -c 2runappconf2b.cfg -s 9951
user runapp -c 2runappconf2c.cfg -s 10177
user runapp -c 2runappconf3.cfg -s 10406
user runapp -c 2runappconf3b.cfg -s 9892
user runapp -c 2runappconf3c.cfg -s 19662
user runapp -c 2runappconf4.cfg -s 10372
user runapp -c 2runappconf4b.cfg -s 9939
user runapp -c 2runappconf4c.cfg -s 9798
user runapp -c 2runappconf5.cfg -s 10604
user runapp -c 2runappconf5b.cfg -s 10043
user runapp -c 2runappconf5c.cfg -s 9907
user runapp -c 2runappconf6.cfg
user runapp -c 2runappconf6.cfg -s 9999
user runapp -c 2runappconf7.cfg -s 1173752
user2 application2 argument1 -c configile01.cfg argument2
user2 application2 argument1 -c configile02.cfg argument4
user2 application2 argument1 -c configile03.cfg argument6
user2 application2 argument1 -c configile04.cfg argument8
user2 application2 argument1 -c configile05.cfg argument9
user3 application3 argument1 argument2 argument9
user3 application3 argument1 argument2 argument10
user3 application3 argument1 argument2 argument10
[appuser@dupprocess (0)]$/usr/xpg4/bin/awk -f dup.awk ps.out
user runapp -c 2runappconf1.cfg
user runapp -c 2runappconf1c.cfg
user runapp -c 2runappconf2.cfg -s 10405
user runapp -c 2runappconf2.cfg -s 10444
user runapp -c 2runappconf6.cfg
user runapp -c 2runappconf6.cfg -s 9999
user3 application3 argument1 argument2 argument10
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP