awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行(下文解释),并在这些行上进行你想要的操作(下文解释)。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。
- 寻找匹配的特定模式的行:
在遍历每一行的时候,可以根据自己的逻辑选出符合条件的行,比如:
1.这一行的内容匹配正则表达式;
2.第一个域的值为“java”;
3.第一个域的值小于的第二个域的值;
4.选择第i行到第j行
等等这些逻辑。这些特定的模式放在{}前面
- 在这些行上进行你想要的操作:
可以有选择的打印这一行的某几个域,也可以先对这个域的值进行一些处理比如分割等再打印。想要的操作放在{}里
下面是我写的一个例子:
1.首先收集mysql相关进程和java相关进程的CPU和内存信息,将结果保存到topjava.tmp文件里,文件内容如下:
11699 root 20 0 103m 1368 1136 S 0.0 0.0 0:00.00 mysqld_safe
11808 mysql 20 0 120m 29m 4996 S 0.0 1.0 1:02.78 mysqld
24252 root 20 0 848m 75m 6048 S 0.0 2.7 0:11.80 java
24283 root 20 0 1465m 255m 8416 S 0.0 9.1 1:39.29 java
2.读取topjava.tmp文件,这个文件有两行都包括java,也就是系统有两个java进程
3.通过比较进程号,分别获取大的进程号和小的进程号
4.再一次读取topjava.tmp文件,然后将第三部获取的大小进程号变量引进来,最后进行逻辑判断将每一行的数据写到指定的文件上:
- 大进程号的java写到/home/tanchao/collectinfo10second/bigjava.txt
- 小进程号的java写到/home/tanchao/collectinfo10second/smalljava.txt
- mysqld_safe写到/home/tanchao/collectinfo10second/mysqld_safe.txt
- mysqld写到/home/tanchao/collectinfo10second/mysqld.txt
top -b -n 1|grep -E 'mysql|java'>'topjava.tmp'
pid1="$(cat topjava.tmp|awk '/java/'|awk 'NR==1,NR==1{print $1}')"
pid2="$(cat topjava.tmp|awk '/java/'|awk 'NR==2,NR==2{print $1}')"
#echo $pid1
#echo $pid2
if [ $pid1 -gt $pid2 ];then
max=$pid1;
min=$pid2;
else
max=$pid2
min=$pid1;
fi
#iecho $max
#echo $min
#cat topjava.tmp
cat topjava.tmp|awk -v maxpid=$max -v minpid=$min '{
now=strftime("%y/%m/%d/%H/%M/%S")
if($12=="java"){
if($1==maxpid)
{
print "time:" now " name:" $12 " pid:" $1 " virt:" $5 " res:" $6 " %cpu:" $9 " %mem:" $10 >> "/home/tanchao/collectinfo10second/bigjava.txt"
}else if($1==minpid){
print "time:" now " name:" $12 " pid:" $1 " virt:" $5 " res:" $6 " %cpu:" $9 " %mem:" $10>>"/home/tanchao/collectinfo10second/smalljava.txt"
}
}else if($12=="mysqld_safe"){
print "time:" now " name:" $12 " pid:" $1 " virt:" $5 " res:" $6 " %cpu:" $9 " %mem:" $10>>"/home/tanchao/collectinfo10second/mysqld_safe.txt"
}else if($12=="mysqld"){
print "time:" now " name:" $12 " pid:" $1 " virt:" $5 " res:" $6 " %cpu:" $9 " %mem:" $10>>"/home/tanchao/collectinfo10second/mysqld.txt"
}
}'
#|awk '{print "name:" $12 " pid:" $1 " virt:" $5 " res:" $6 " %cpu:" $9 " %mem:" $10}'
#cat topjava.tmp|awk -v pid=$minpad '$pid'|awk '{print "name:" $12 " pid:" $1 " virt:" $5 " res:" $6 " %cpu:" $9 " %mem:" $10}'
cat /dev/null>topjava.tmp
后台执行shell脚本
对于上面的脚本,我要每10秒执行一次,由于 crontab的最小执行单位是分钟,于是使用nohup,编写startCollect.sh脚本:
while [ true ]; do
/bin/sleep 10
sh memcpu.sh
done
后台运行此脚本:
nohup sh startCollect.sh &
参考资料:
Awk学习笔记
http://man.lupaworld.com/content/manage/ringkee/awk.htm#id2809145
sed、awk调用shell变量的方法
http://findingcc.blog.51cto.com/1045158/234458
linux正则表达式 grep egrep用法
http://www.cnblogs.com/caibird2005/archive/2009/04/14/1436008.html
shell脚本实现每秒执行一次任务
http://www.gaojinbo.com/shell%E8%84%9A%E6%9C%AC%E5%AE%9E%E7%8E%B0%E6%AF%8F%E7%A7%92%E6%89%A7%E8%A1%8C%E4%B8%80%E6%AC%A1%E4%BB%BB%E5%8A%A1.html