linux三剑客
sed 数据修改
grep 数据查找定位
awk 数据切片
正则表达式 基本正则 ^开头 $ 结尾 [a-z][0-9]区间,如果开头带有^表示不能匹配区间内的元素 *0个或者多个 .表示任意字符
扩展正则 ?非贪婪匹配 +一个或者多个 ()分组 {}范围约束 |匹配多个表达式的任何一个
正则就是记录文本规则的代码
匹配以字母a开头的单词\ba\w*\b
匹配刚好6个字符的单词\b\w(6)\b
匹配1个或更多连续的数字\d+
5位大12位QQ号^\d(5,12)$
grep选项
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-E 使用扩展正则表达式
-A -B -C 打印命中数据的上下文
grep pattern -r dir/ 递归搜索
查找文件内容包含root的行数
grep -n root test.txt
查找文件内容不包含root的行
grep -nv root test.txt
查找文件内容以s开头的行
grep ^s test.txt
查找文件内容以n结尾的行
grep $n test.txt
sed 是流编辑器,一次处理一行内容
-e 表达式 多表达式
-n 指定文件夹
a :新增 sed -e "4 a newline"
新增在指定行后面
c : 取代 sed -e "2,5c No 2-5 number"
d : 删除 sed -e "2,5d"
i : 插入 sed -e "2i newline"
插入在指定行前面
p :打印 sed -n '/root/p' sed -n '2p'打印第二行
全局替换g
s :取代 sed -e 's/old/new/g' 可以把、替换成#或者&
-i 直接修改源文件
-E 扩展表达式
--debug 调试
直接修改文件内容
s :取代 sed -i 's/old/new/g'
g 代表全局
查看帮助
man sed j向下翻 k向上翻 / 查找匹配字符 n查找下一个 N查找上一个
20 30,35 行数与行数范围
/pattern/ 正则匹配
//,//正则匹配的区间,第一个表示开始命中,第二个表示结束命中,类似开闸放水
分组匹配与字段提取:sed 's#([0-9]*)|([a-z]*)#\1 \2#'
awk 把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分在进行后续处理 语法 awk 'pattern{action}'
常用参数
FILENAME awk浏览的文件名
BEGIN 处理文本之前要执行的操作
END 处理文本之后要执行的操作
FS 设置输入域分隔符,等价于命令行-F选项 字段分隔符 -F 参数指定字段分隔符,可以用|指定多个可能的分隔符-F'<|>' BEGIN{FS="_"}也可以表示分隔符
NF 浏览记录的域的个数(列数)字段数
NR 已读的记录数(行数) 记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
$0 代表当前整条记录
$1 标识当前行的第一个域 ...以此类推
$NF 最后一个字段 $(NF-1) 代表倒数第二个字段
awk 'BEGIN{}END{}' 开始和结束
awk '/kdjg/' 正则匹配
awk '/aa/,/bb/' 区间选择
awk '$2~/404|500/' 字段匹配
awk 'NR==2' 取第二行
awk 'NR>1' 去掉第一行
awk ''
搜索/etc/passwd 有root关键字的所有行,并显示对应的shell
awk -F : '/root/{print$7}' /etc/passwd
打印/etc/passwd的第二行信息
awk -F:'NR==2{print$0}' /etc/passwd
使用begin加入标题
awk -F : 'BEGIN{print "BEGIN BEGIN"} {print $1,$2}' /etc/passwd
自定义分隔符
echo "11 22|33 44|55 66"|awk 'BEGIN{RS="|"}{print$0}'
awk 字段分割
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | awk -F / '{print $1,$2,$3,$4,$5}'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | awk 'BEGIN{FS="/"}{print $1,$2,$3,$4}'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | awk 'BEGIN{FS="/|_"}{print $1,$2,$3,$4}'
修改OFS和ORS让$0重新计算
echo $PATH |awk 'BEGIN{FS=":"};OFS=" | "{$1=$1;print $0}'
echo $PATH |awk 'BEGIN{RS=":"};ORS=" ^ "{print NR,$0}'
把单行分拆为多行
echo $PATH | awk 'BEGIN{RS=":"}{print $0}'
多行组合为单行
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | awk 'BEFIN{ORS=":"}{print $0}'
数据计算
echo '1,10
2,20
3,30' |awk 'BEGIN{a=0;FS=","}{a+=$2}END{print a}'
awk的词典结构
提取包含"9期"但不包含"学员"的记录
awk -F,'/9期/{if(member[$1]!=1)d[$1]=$0}/学员/{member[$1]-1;delete d[$1]} END {for(k in d)print d[k]}' file
bash的编程语法
变量 :命名只能使用英文字母,数字和下划线,首个字符不能以数字开头 中间不能有空格,可以使用下划线(——) 不能使用标点符号 不能使用bash里的关键字(可用help命令查看保留关键字)
定义和使用变量 test1="abcde",echo $test1 unset test1 删除变量
数组初始化 my_arry=(a b c d) echo ${my_arry[0]}
控制语句
if if ; then ;fi -eq(等于) -lt(小于) -gt(大于) if [ $a -eq $b ] ; then echo "equle" ; elif [ $a -lt $b ] ; then echo "small" ; elif [ $a -gt $b ] ; then echo "big" ; fi
for for i in $(cat 1.txt) ; do echo $i ; done
while while read i ; do echo $i ;done<1.txt
curl jq
shell输入输出
Read 用来读取输入、并赋值给变量
echo 、print 可以简单输出变量
>file 将输出重定向到另一个文件
>> 表示追加 等价于tee -a
<file 输入重定向
| 表示管道 ,也就是前一个命令的输出转入下一个命令的输入
文件
进程 top ps -aux | less
网络 netstat -tlnp -tnp
练习分析日志
函数
定义函数 online(){ w | sed '1,2d' | awk 'print $1' |sort |uniq -c | wc -l } 调用函数online
cpu_mem(){ top -b -n 1 -d 1 | grep -i titan_monitor$ |awk '{print $9,$10}';}
参数化写法
调用 cpu_mem top
cpu_mem(){ top -b -n 1 -d 1 | grep -i $1 |awk '{print $9,$10}';}
set -x 打开调试
set +x 关闭调试
打印对应文档列数
less dbank-flow-amg-serviceAll.log | awk '{for(i=0;i<=NF;i++) print "$"i"="$i}' |less
打印对应文档列数函数
print_lieshu(){ less dbank-flow-amg-serviceAll.log | awk '{for(i=0;i<=NF;i++) print "$"i"="$i}' | less ;}
打印响应时间最大的三个及对应的url
maxtime_and_url(){
less nk.log | awk 'print $7,$(NF-1)' | sort -nr -k 2 | head -3
}
打印所有url的平均响应时间
less nk.log | awk '{sum+=$(NF-1)}END{print sum/NR}'
awk 词典 分类汇总 打印每个url的平均响应时间,且按照响应时间进行排序
less nk.log | awk '{time[$7]+=$(NF-1);count[$7]+=1}END{for(k in time) print k,time[k]/count[$7]}' |sort -nr -k 2
统计每个url的顶层路由的qps的top5
less nginx.log | awk '{print $4,$7}'|sed 's#[?!].*##' | sed -E 's#([^ ]*) *(/[^/]*).*#\1:\2#'|sort |awk -F : 'BEDIN{min=0;max=0;}{count[$NF]+=1;cur=$3*60+$4;if(cur<min) min=cur;if(cur>max) max=cur;}END{ for (i in count) print i count[i]/(max-min+1)}'|sort -k2 -nr |head -5