grep and awk

--
转载地址:http://hi.baidu.com/du_hu999/blog/item/3e29561e7cf9c112413417bf.html

grep  

显示查出的行在原文件的行号加n参数 grep -n root /etc/passwd  
反向查找加v参数  grep -v bin /etc/passwd
大小写不敏感加i参数  grep -ni root grep.txt 

查找出有rot或者是rat的行 grep -n r[oa]t grep.txt --注意的是,[ ]括号内不论几个字符,都是选一个

查找不以r开头的*oot的行 grep  '[^r]oot' grep.txt

查找不以小写字母开头  grep  '[^a-z]oo' grep.txt  

查找不以大写字母开头   grep '[^[:upper:]]oo' grep.txt 
   grep  '[^A-Z]oo' grep.txt 

查找有数字的号   grep '[0-9]' grep.txt 
  或者 grep [[:digit:]] grep.txt 

行首^    行尾$

查找以数字开头的   grep ^[0-9]  grep.txt 
  grep ^[[:digit:]] grep.txt 

查找以大写字母开头的 grep ^[A-Z] grep.txt 或者 grep ^[[:upper:]] grep.txt 
查找以小写字母开头的 grep ^[a-z] grep.txt 或者 grep ^[[:lower:]] grep.txt 

查找以点结束的   grep "\."$ grep.txt  --注意要引起来,而且要转义

去掉空格行    cat  grep.txt  |grep -v ^$ --以^$表示空格行

.  点号代表一个任意字符
*  代表零个或者多个前字符
grep 'G..g' grep.txt

---------------------------------------------------------------------

awk

调用有三种方式:

1,awk   -F"分隔符"  "command" filename
2,将所有命令插入一个文件,使它权限程序可执行,然后当成脚本调用它
3,是将所有的awk命令插入一个单独文件,然后调用
  awk -f awk-script-file  filename

字段的引用
$ 字段操作符
$1代表第一列,$2代表第二列。。。n以此类推
$0代表整个输入记录

比较用cut和awk截取IP
ifconfig eth0 |grep Bcast |cut -d ":" -f2|cut -d" " -f1

ifconfig eth0 |grep Bcast |awk -F: '{print $2}'|awk  '{print $1}'

打印所有行    awk '{print $0}' /etc/passwd
打印第一列  awk -F: '{print $1}' /etc/passwd
打印第一,三列  awk -F: '{print $1"\thaha\t"$3}' /etc/passwd

$n    n不一定要用整数,也可以用变量值代替
echo a b c |awk 'BEGIN {one=1;two=2} {print $(one+two)}'

awk  -F:  ‘BEGIN {处理文件前执行的代码块} {处理文件过程中执行的代码块} END {处理文件后执行的代码块}'   filename

在打印前和打印后加上一些信息
awk -F: 'BEGIN {print "@@@@@@@@@@@@@@@@@@@@@@@@@"} {print $0} END {print "======================="}' /etc/passwd

---------------------------------
--awk  内置变量

FS   设置分隔符,等同于-F
NF   代表字段数
$NF  代表最后一个字段数
NR   代表当前处理第几行
---------------------------------

练习:用netstat -ntl 截取所有开放的端口号

 netstat -ntl |grep -v Active| grep -v Proto|awk '{print $4}'|awk -F: '{print $NF}'

打印每一行的最后一列 awk -F: '{print $NF}' /etc/passwd
  或者awk  '{FS=":"} {print $NF}' /etc/passwd

打印第五行awk 'NR==5 {print $0}' /etc/passwd
  或者 awk '{if (NR==5) print $0}' /etc/passwd

打印每行的字段数 awk  -F: '{print NF}' /etc/passwd
打印第五行的字段数  awk  -F: 'NR==5 {print NF}' /etc/passwd

打印最后一行awk -F: ' END {print $0} ' /etc/passwd
打印最后一行的最后一列 awk -F: ' END {print $NF} ' /etc/passwd
  或者:awk -F: '{a=$NF}END {print a} ' /etc/passwd

---------------------------
awk关系操作符
==   等于
!=    不等于
>    大于
<    小于
>=   大于等于
<=   小于等于

awk逻辑操作符
&& 逻辑与
| | 逻辑或
! 非
-----------------------------

打印字段数大于5的行awk -F: 'NF>5 {print $0}' /etc/passwd

打印文件的所有的字段数的总和  awk -F: 'BEGIN { a=0} {a=a+NF} END {print a}' /etc/passwd

打印uid大于等于500的行awk -F: '$3>500 {print $0}' /etc/passwd
  或awk -F: '{if ($3>500) print $0}' /etc/passwd

打印5到10行 awk -F: 'NR>=5 && NR<=10 {print $0}' /etc/passwd
  或awk -F: '{if (NR>=5 && NR<=10) print $0}' /etc/passwd

打印字段数大于5的总行数 awk -F: 'BEING {c=0} {if (NF>5) {c=c+1}} END {print c}' /etc/passwd 
 
awk运算操作符
+ - * / %
^  幂   比如:2的三次方  2^3

  
隔行打印(隔行删除)
打印奇数行(删除偶数行) awk -F: 'NR%2!=0 {print $0}' /etc/passwd
打印偶数行 (删除奇数行) awk -F: 'NR%2==0 {print $0}' /etc/passwd

综合运算  echo |awk '{print 10^2+(90-80)}'

也可以进行浮点数运算 echo |awk '{print 10.9^2+(90.5-80.2)/3}'

 例1,计算swap总量,使用量,剩余量,使用百分比,剩余百分比 

total    used    free   used%     free%
4096564     0       4096564  0%         100%

free |grep Swap |awk 'BEGIN {print "total\tused\tfree\tused%\t\tfree%\t"} {print $2"\t"$3"\t"$4"\t"$3/$2*100"\t"$4/$2*100}'

--awk外部脚本

脚本的结构

BEGIN {
}
{
}
END {
}

例 :把 awk -F: '{print $1}' /etc/passwd 改成写外部脚本的形式

vim awk01.awk
 
BEGIN {
        FS=":" --注意,外部脚本需要使用变量FS指定分隔符
}
{
        print $1
}
调用方法:
 awk -f awk01.awk /etc/passwd

赋值操作符:
++ 自加1
-- 自减1
+= 把加的结果赋值给变量
-= 
*=
/=
%=
^=

统计文件的空行数
vim awk02.awk
/^$/  {
        print a +=1   --等同于++a
}

[root@li shell04]# awk -f awk02.awk /etc/inittab 
1
2
3
4
5
6
7
8
9

--匹配空行,就把a的值加1,在遇到第一个空行之前值为0,所以遇到九次空行,打印了九次

vim awk03.awk
/^$/  {
        print a++
}

[root@li shell04]# awk -f awk03.awk /etc/inittab 
0
1
2
3
4
5
6
7
8
--从上面两个例子可以看出a+=1是先赋值再打印,a++是先打印再赋值

vim awk04.awk

/^$/    {
        ++a   --等同于a+=1
}
END     {
        print a
}

[root@li shell04]# awk -f awk04.awk /etc/inittab 
9  --得到空行的结果  9

例:  打印字段数大于5的总行数  (用脚本写)
awk -F: 'BEING {c=0} {if (NF>5) {c=c+1}} END {print c}' /etc/passwd 

转换成脚本awk05.awk
BEGIN {
     a=0
     FS=":"
}
{
        if (NF>5)
        {a=a+1}
}
END {
        print a
}

[root@li shell04]# awk -f awk05.awk /etc/passwd
79

 例:找出目录下的最大的文件和最小的文件,输出平均大小
思路: ls 有一个参数大写字母S,会把文件从大到小排序,排序后,最大文件就是第一行(NR=1),最小文件就是最后一行,平均大小为(累计总大小/NR);注意 grep -v 总计 这句如果是英文件系统,就换成grep -v Total

[root@li shell04]# ls -lS |grep -v 总计 |awk 'BEGIN {total=0;min=0} {total+=$5;min=$5; if (NR==1) {print "max size:" $5"\t"$NF}} END {print "min size: "min"\t"$NF"\navarage size:" total/NR}'

max size:6613   shell04.txt
min size: 21    awk03.awk
avarage size:1665.75

BEGIN {
        total=0
        min=0
}
{
        total=total+$5
        min=$5
        if(NR==1) {
                print "max size:" $5"\t"$NF
        }

}
END {
        print "min size:" min"\t"$NF
        print "avarage size:" total/NR
}

调用此脚本的方法:  ls -lS |grep -v 总计 |awk -f awk06.awk 

利用printf格式化输出

 [root@li shell04]# awk 'BEGIN {print "hello world"}'
hello world
[root@li shell04]# awk 'BEGIN {printf "hello world"}'
hello world[root@li shell04]# 

--从上面看到print和printf直接使用的主要区别就是printf不自动换行,需要使用\n来换行

格式:
printf {format_expression[,argument]}
两个主要的格式说明符是s和d,s代表字符串,d表示十进制整数

[root@li shell04]# ls -l|grep -v 总计|awk '{printf ("%d%s",$5,$NF)}'
32awk01.awk23awk02.awk21awk03.awk32awk04.awk72awk05.awk175awk06.awk7421shell04.txt7338shell04.txt~[root@li shell04]# 

[root@li shell04]# ls -l|grep -v 总计|awk '{printf ("%d\t%s\n",$5,$NF)}'
32      awk01.awk
23      awk02.awk
21      awk03.awk
32      awk04.awk
72      awk05.awk
175     awk06.awk
7610    shell04.txt
7473    shell04.txt~

 例:倒序排序所有字段(/etc/passwd)

BEGIN {
        FS=":"
}
{
        for (i=NF;i>0;i--){
                if (i != 1) {
                        printf("%s%s",$i,FS)
                }
                else {
                        printf ("%s",$i) 
                }
                }
                printf ("\n")
}
END {
}

调用:
 awk -f awk07.awk /etc/passwd
可以看到结果倒序排列

-------------------------------

--awk字符匹配

==  完全精确匹配
~ 匹配
!~      不匹配

完全匹配
awk -F: '$1==/oo/ {print $0}' /etc/passwd
awk -F: '$1=="oo" {print $0}' /etc/passwd

部分匹配
awk -F: '$1~"oo" {print $0}' /etc/passwd
awk -F: '$1~/oo/ {print $0}' /etc/passwd
 
不匹配
awk -F: '$1!="oo" {print $0}' /etc/passwd
awk -F: '$1!~"oo" {print $0}' /etc/passwd

 例:统计/etc/passwd里以/sbin/nologin结束的用户名,打印出来,并统计个数

[root@li shell04]# awk -F: 'BEGIN {a=0} $NF~/\/sbin\/nologin/ {printf ("%s \t",$1);a++}  END {printf ("\n\ntotal: %s\n",a) }' /etc/passwd

bin     daemon  adm     lp      mail    uucp    operator        games   gopher    ftp     nobody  vcsa    rpc     mailnull        smmsp   nscd    ntp       oprofile        pcap    dbus    avahi   xfs     rpcuser         nfsnobody         sshd    haldaemon       gdm     avahi-autoipd   sabayon  apache   squid   named   hsqldb  dovecot 

total: 34

--awk的字符串函数

长度函数
length()

打印出/etc/passwd的所有用户名,并统计其字符长度
awk -F: '{print $1,length($1)}' /etc/passwd

index  位置函数

找出oo字符串在/etc/passwd的所有用户名内的第几位
awk -F: '{print index($1,"oo")}' /etc/passwd

大小转换
toupper
tolower

awk -F: '{print tolower(toupper($1))}' /etc/passwd

substr  截取函数
awk -F: '{print substr($1,1,2)}' /etc/passwd

替换函数
sub  单替换
gsub  全替换

[root@li shell04]# awk -F: 'NR==1 {sub(/o/,"O",$0);print $0}' /etc/passwd 
rOot:x:0:0:root:/root:/bin/bash

[root@li shell04]# awk -F: 'NR==1 {gsub(/o/,"O",$0);print $0}' /etc/passwd 
rOOt:x:0:0:rOOt:/rOOt:/bin/bash

作业题:
 1,监控磁盘使用率,高于80%的找出来,输出警告,发送邮件给管理员

df -h |grep -v 容量|awk '{print $1,$5}'|awk -F% '{print $1}' |while read  a
do
                used=`echo $a| awk '$2>80 {print $1" is used:" $2"% warning!!!!!!!"}'`
                echo $used >> /tmp/used.txt
done
mail -s "disk warnning"  root@li.cluster.com  < /tmp/used.txt


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值