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} 调整一下顺序,把第一项放后面来