Linux三剑客--grep,sed,awk    

Linux三剑客--grep,sed,awk

一、grep  基于正则表达式,查找满足条件的行

    常用参数 :

-v 显示不被pattern 匹配到的行

-i 忽略字符大小写

-n 显示匹配到的行号

-c 统计匹配到的行数

-o 仅显示到的字符串

-E 表示后面接正则表达式 (后面使用|来分割多个项)

grep -n root file.txt  #查找file.txt 文件中包含root 的行(包含行号)grep -nv root file.txt  #查找file.txt 文件中不包含root 的行(包含行号)grep  ^s  file.txt  #查找以s 开头的行grep  n$  file.txt  #查找以n 结尾的行grep -r ddd  mm/ #在当前目录的mm 目录下循环查找包含dddd 字符串的内容

 二、sed 流编辑器,根据指定到的数据行编辑数据

sed 只是对文件的某行进行了处理,但是并不会修改文件本身的内容(-i) 除外

常用参数:

-e 后面加脚本

-i 直接修改文本的内容

-n 仅显示script处理后的结果

动作参数:

a:新增  sed -e '4 a hello' 

c:取代  sed -e '2,5c hello world' 

d:删除  sed -e '2,5d'

i:插入 sed -e '2i newline'

p:打印 sed -n '/root/p'    通常和-n 参数一起使用

s:取代  配合g 指定范围为全局

sed -n '/root/p' a.txt  # 在啊a.txt 中打印出包含root 字符串的行(如果不加-n 会打印出文件中所有的行) sed -e '4 a newline' test.py  #在第四行后添加新的字符串 newline ---并输出到屏幕sed '4,5c No 4-5 number' file.txt   #把第4-5行替换为 NO 4-5 newbersed '2,3d' file.txt   #删除file.txt  的内容(删除第一行到第三行)sed -e 's/root/hello/g' file.txt   #替换   全局搜索 把root 替换为hello  sed -i 's/root/hello/g' file.txt   #全局搜索,root替换为hello 直接修改文件内容

 三、awk 针对数据进行切片处理

 根据定位到的数据进行片段处理。awk 是一个非常强大的命令工具 理论上是可以替换grep 的 

格式:  awk [选项参数] 'script' var=value file(s)   

   模式:    

    • 正则表达式模式 : awk   /正则表达式/    用// 括起来 
    • 语句块模式:awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file
    • 匹配模式:用运算符~(匹配)和!~(不匹配)

常用参数:

-F   指定分隔符,如果不指定默认为空格 

内置变量:

RS:指定换行符

FS:字段分隔符,等价于 -F 

NR:已读的记录数(行数)

NF:域的个数(列数)

$n: 指定字段   $0 代表整行,$n 代表第n 项

一些基本的操作 

awk '{print $1,$4}' a.txt #输出第一列,第四列(或者理解成第一项和第四项)awk '/Running/' a.txt   #输出带有这个字符串的行  awk '/456/,/ing/' a.txt  #区间选择  筛选出 456-ing 中间的内容awk  'NR==2'  a.txt  #行匹配   匹配第2行 cat a.txt|awk -F: '$1~/hello/{print NR,$1,$2}'     #第一项匹配正则表达式 hello 字符串,之后输出行号,第一项,第二项awk 'length>12' a.txt   #查找文件中长度大于 12 的行高级一些 
awk -F: '{print $1,$4}' file.txt #执行引号内的脚本(脚本的功能是打印每行的第一项和第四项)   其中设置的分隔符为 :(不指定默认为tab 键和空格)awk  '$1=="hello"{print $1,$2}' file.txt  #匹配第一项等于hello的行  就输出第一项第二项echo "111 222|333 444|555 666"|awk 'BEGIN{RS="|"}{print $0}'   #自定义换行符为|

 

awk 编程     

定义变量   awk -v 变量名称 =变量值 

awk -va=1 '{print $1,$1+a}' a.txt

条件语句 

if (expression) {
    statement1;
} else if (expression1) {
    statement2;
} else {
    statement3;
}
ls -l |awk 'BEGIN {size=0;print size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' #统计内部不等于4096的文件的大小 并输出总和

数组 

awk -F: 'BEGIN{count=0}{name[count]=$1}END{for(i=0;i<NR;i++) print i,name[i]}' /etc/passwd

 实战 

一、显示 /etc/passwd 的账户 

#cat /etc/passwd |awk  -F ':'  '{print $1}'  root
daemon
bin

二、如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割,并在开头加上开始符 ,最后加上结束符

#cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"} {print $1"\t"$7} END{print “end”}'name     shell
root    /bin/bash
daemon  /bin/sh
bin     /bin/sh
end

三、拆分文件,使用重定向就可以了  

ls -l |awk 'NR!=1{print >$6}'    #根据第六项 进行文件分类拆分  这时候就会在当前文件下出现以第六项日期进行划分的文件

四、统计nginx.log 文件中400,500 的报错,文件行是以空格分隔,状态码在第9项 

less nginx.log| awk '$9~/404|500/'

五、计算所有 .cpp .h .c 文件的总和

ls -l *.cpp *.c *.h|awk 'BEGIN{size=0}{size+=$5}END{print size}'

六、统计每个用户的进程占了多少内存

ps aux|awk 'BEGING{size=0} NR!=1{a[$1]+=$6} END{for(i in a) print i,a[i] "kb"}'结果:472 29360kb
dbus 1776kb
polkitd 8612kb
libstor+ 468kb
ntp 1528kb
root 294404kb

七、统计所有链接端口的IP地址链接状态,并展示状态数量 

netstat -tn|awk 'NR>2{print $4,$6}'|awk -F: '{print $2}'|sort|uniq -c|sort -nr|awk '{print $2" " $3" " $1}分析: netstat  -t 展示tcp协议   -n 以数字形式展示ip 和端口 
      awk 'NR>2{print $4,$6}'  去除前两行    以空格为分隔展示第四和第六项
      awk -F: '{print $2}'    以:为分隔符  展示第二项,也就是端口后面的项
      sort|uniq -c  先排序  再去重  (去重前最好排序一下,去重会自动把数量统计出来)
      sort -nr   按数字逆序排列(因为默认是按ascii  排序的,所以要指定以n 也就是数字形式进行排序)
      awk '{print $2" " $3" " $1}    调整一下顺序,把第一项放后面来