awk使用笔记
awk特殊字符打印方法:
1、awk打印双引号:
awk '{print "\""}'
2、awk打印单引号:
awk '{print "'\''"}'
awk关系运算符及其意义:
1、< :小于 2 、> :大于 3、<=:小于等于 4、>=:大于等于 5、==:等于 6、!=不等于 7、~:匹配正则表达式 8 !~:不匹配正则表达式
awk算数运算符及其意义:
+ 加 -:减 *:乘 /:除 %:模 ^或者**:乘方 ++x:在返回x志之前 x变量加1 x++ :在返回x值之后,x加1
awk常用变量名及意义:
变量名 含义
ARGC 命令行变元个数
ARGV 命令行变元数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符,默认为一个空格
RS 输入记录分隔符
NF 当前记录里域个数
NR 到目前为止记录数
OFS 输出域分隔符
ORS 输出记录分隔符
awk 布尔运算符:
|| :逻辑或 && :逻辑与 !:逻辑非
awk 内置字符串函数
gsub(r,s) 在输入文件中用s替换r
gsub(r,s,t)在t中用s替换r
index(s,t)返回s中字符串第一个t的位置
length(s) 返回s的长度
match(s,t)测试s是否包含匹配t的位置
split(r,s,t)在t上将r分出序列s
sub(r,s,t) 将t中第1次出现的r替换为s
substr(r,s)返回字符串r中s开始的后缀部分
substr(r,s,t)返回字符串r中从s开始长度为t的后缀部分
awk 常用场景使用:
分析nginx 日志:
1、统计日志中访问最多的10个IP地址:
方法1:$ awk '{a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
方法2:$ awk '{print $1}' access.log |sort |uniq -c |sort -k1 -nr |head -n10
2)统计日志中访问大于100次的IP
方法1:$ awk '{a[$1]++}END{for(i in a){if(a[i]>100)print i,a[i]}}' access.log
方法2:$ awk '{a[$1]++;if(a[$1]>100){b[$1]++}}END{for(i in b){print i,a[i]}}' access.log
3)统计2016年4月9日一天内访问最多的10个IP
方法1:$ awk '$4>="[9/Apr/2016:00:00:01" && $4<="[9/Apr/2016:23:59:59" {a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
方法2:$ sed -n '/[9/Apr/2016:00:00:01/,/[9/Apr/2016:23:59:59/p' access.log |sort |uniq -c |sort -k1 -nr |head -n10 #前提开始时间与结束时间日志中必须存在
4)统计当前时间前一分钟的访问数
grep -c $(date -d '-1 minute' +%d/%b/%Y:%H:%M) access.log
5)统计访问最多的前10个页面($request)
$ awk '{a[$7]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
6)统计每个URL访问内容的总大小($body_bytes_sent)
$ awk '{a[$7]++;size[$7]+=$10}END{for(i in a)print a[i],size[i],i}' access.log
7)统计每个IP访问状态码数量($status)
$ awk '{a[$1" "$9]++}END{for(i in a)print i,a[i]}' access.log
8)统计访问状态码为404的IP及出现次数
$ awk '{if($9~/404/)a[$1" "$9]++}END{for(i in a)print i,a[i]}' access.log
多文件处理
2、两个文件对比
1)找出a和b文件相同记录
方法1:$ awk 'FNR==NR{a[$0];next}($0 in a)' a b
2)找不同记录(同上,取反)
$ awk 'FNR==NR{a[$0];next}!($0 in a)' a b
$ awk 'FNR==NR{a[$0]=1;next}!a[$0]' a b
$ awk 'ARGIND==1{a[$0]=1}ARGIND==2&&a[$0]!=1' a b
$ awk 'FILENAME=="a"{a[$0]=1}FILENAME=="b"&&a[$0]!=1' a b
3、合并两个文件
1)将d文件性别合并到c文件
$ cat c
zhangsan 100
lisi 200
wangwu 300
$ cat d
zhangsan man
lisi woman
方法1:$ awk 'FNR==NR{a[$1]=$0;next}{print a[$1],$2}' c d
zhangsan 100 man
lisi 200 woman
wangwu 300 man
方法2:$ awk 'FNR==NR{a[$1]=$0}NR>FNR{print a[$1],$2}' c d
说明:NR==FNR匹配第一个文件,NR>FNR匹配第二个文件,将$1为数组下标
方法3:$ awk 'ARGIND==1{a[$1]=$0}ARGIND==2{print a[$1],$2}' c d
2)将a.txt文件中服务名称合并到一个IP中
$ cat a.txt
192.168.2.100 : httpd
192.168.2.100 : tomcat
192.168.2.101 : httpd
192.168.2.101 : postfix
192.168.2.102 : mysqld
192.168.2.102 : httpd
$ awk -F: -vOFS=":" '{a[$1]=a[$1] $2}END{for(i in a)print i,a[i]}' a.txt
$ awk -F: -vOFS=":" '{a[$1]=$2 a[$1]}END{for(i in a)print i,a[i]}' a.txt
192.168.2.100 : httpd tomcat
192.168.2.101 : httpd postfix
192.168.2.102 : mysqld httpd
说明:a[$1]=$2 第一列为下标,第二个列是元素,后面跟的a[$1]是通过第一列取a数组元素(服务名),结果是$1=$2 $2,并作为a数组元素。
3)将第一行附加给下面每行开头
$ cat a.txt
xiaoli
a 100
b 110
c 120
$ awk 'NF==1{a=$0;next}{print a,$0}' a.txt
$ awk 'NF==1{a=$0}NF!=1{print a,$0}' a.txt
xiaoli a 100
xiaoli b 110
xiaoli c 120
4、倒叙列打印文本
$ cat a.txt
xiaoli a 100
xiaoli b 110
xiaoli c 120
$ awk '{for(i=NF;i>=1;i--){printf "%s ",$i}print s}' a.txt
100 a xiaoli
110 b xiaoli
120 c xiaoli
$ awk '{for(i=NF;i>=1;i--)if(i==1)printf $i" ";else printf $i" "}' a.txt
说明:利用NF降序输出,把最后一个域作为第一个输出,然后自减,print s或print ""打印一个换行符
5、从第二列打印到最后
方法1:$ awk '{for(i=2;i<=NF;i++)if(i==NF)prin
tf $i" ";else printf $i" "}' a.txt
方法2:$ awk '{$1=""}{print $0}' a.txt
a 100
b 110
c 120
6、将c文件中第一列放到到d文件中的第三列
$ cat c
a
b
c
$ cat d
1 one
2 two
3 three
方法1:$ awk 'FNR==NR{a[NR]=$0;next}{$3=a[FNR]}1' c d
说明:以NR编号为下标,元素是每行,当处理d文件时第三列等于获取a数据FNR(重新计数1-3)编号作为下标。
方法2:$ awk '{getline f<"c";print $0,f}' d
1 one a
2 two b
3 three c
1)替换第二列
$ awk '{getline f<"c";gsub($2,f,$2)}1' d
1 a
2 b
3 c2)替换第二列的two
$ awk '{getline f<"c";gsub("two",f,$2)}1' d
1 one
2 b
3 three
7、数字求和
方法1:$ seq 1 100 |awk '{sum+=$0}END{print sum}'
方法2:$ awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++}print sum}'
方法3:$ awk 'BEGIN{for(i=1;i<=100;i++)sum+=i}END{print sum}' /dev/null
方法4:$ seq -s + 1 100 |bc
8、每隔三行添加一个换行符或内容
方法1:$ awk '$0;NR%3==0{printf " "}' a
方法2:$ awk '{print NR%3?$0:$0" "}' a
方法3:$ sed '4~3s/^/ /' a
9、字符串拆分
方法1:
$ echo "hello" |awk -F '' '{for(i=1;i<=NF;i++)print $i}'
$ echo "hello" |awk -F '' '{i=1;while(i<=NF){print $i;i++}}'
h
e
l
l
o
方法2:
$ echo "hello" |awk '{split($0,a,"''");for(i in a)print a[i]}' #无序
l
o
h
e
l
10、统计字符串中每个字母出现的次数
$ echo a,b.c.a,b.a |tr "[,. ]" " " |awk -F '' '{for(i=1;i<=NF;i++)a[$i]++}END{for(i in a)print i,a[i]|"sort -k2 -rn"}'
a 3
b 2
c 1
11、第一列排序
$ awk '{a[NR]=$1}END{s=asort(a,b);for(i=1;i<=s;i++){print i,b[i]}}' a.txt
说明:以每行编号作为下标值为$1,并将a数组值放到数组b,a下标丢弃,并将asort默认返回值(原a数组长度)赋值给s,使用for循环小于s的行号,从1开始到数组长度打印排序好的数组。
12、删除重复行,顺序不变
$ awk '!a[$0]++' file
博客地址:http://lizhenliang.blog.51cto.com
QQ群:323779636(Shell/Python运维开发群)
13、删除指定行
删除第一行:
$ awk 'NR==1{next}{print $0}' file #$0可省略
$ awk 'NR!=1{print}' file
$ sed '1d' file
$ sed -n '1!p' file
14、在指定行前后加一行
在第二行前一行加txt:
$ awk 'NR==2{sub('/.*/',"txt &")}{print}' a.txt
$ sed'2s/.*/txt &/' a.txt
在第二行后一行加txt:
$ awk 'NR==2{sub('/.*/',"& txt")}{print}' a.txt
$ sed'2s/.*/& txt/' a.txt
15、通过IP获取网卡名
$ ifconfig |awk -F'[: ]' '/^eth/{nic=$1}/192.168.18.15/{print nic}'
16、浮点数运算(数字46保留小数点)
$ awk 'BEGIN{print 46/100}'
$ awk 'BEGIN{printf "%.2f ",46/100}'
$ echo 46|awk '{print $0/100}'
$ echo 'scale=2;46/100' |bc|sed 's/^/0/'
$ printf "%.2f " $(echo "scale=2;46/100" |bc)
结果:0.46
17、替换换行符为逗号
$ cat a.txt
1
2
3
替换后:1,2,3
方法1:
$ awk '{s=(s?s","$0:$0)}END{print s}' a.txt
说明:三目运算符(a?b:c),第一个s是变量,s?s","$0:$0,第一次处理1时,s变量没有赋值初值是0,0为假,结果打印1,第二次处理2时,s值是1,为真,结果1,2。以此类推,小括号可以不写。
方法2:
$ tr ' ' ',' < a.txt
方法3:
$ sed ':a;N;s/ /,/;$!b a' a.txt
说明:第一个标签a,先读取第一行记录1追加到模式空间,此时模式空间内容是1$,执行$!b($!最后一行不跳转,b是控制流跳转命令)跳转到a标签,继续读取第二行记录2追加到模式空间,因为使用N命令,每个记录以换行符( )分割,此时模式空间内容是1 2$,执行将换行符替换逗号命令,继续跳转到a标签...
方法4:
$ sed ':a;$!N;s/ /,/;t a' a.txt
说明:与上面类似,其中t是测试命令,当上一个命令(替换)执行成功才跳转。
方法5:
$ awk '{if($0!=3)printf "%s,",$0;else print $0}' a.txt
说明:3是文本最后一个数
方法6:
while read line; do
a+=($line)
done < a.txt
echo ${a[*]} |sed 's/ /,/g'
说明:将每行放到数组,然后替换
18、把奇数换行符去掉
$ cat b.txt
string
number
a
1
b
2
$ awk 'ORS=NR%2?" ":" "' b.txt #把奇数行换行符去掉
$ xargs -n2 < a.txt #将两个字段作为一行
string number
a 1
b 2
19、费用统计
$ cat a.txt
姓名 费用 数量
zhangsan 8000 1
zhangsan 5000 1
lisi 1000 1
lisi 2000 1
wangwu 1500 1
zhaoliu 6000 1
zhaoliu 2000 1
zhaoliu 3000 1
统计每人总费用、总数量:
$ awk '{name[$1]++;number[$1]+=$3;money[$1]+=$2}END{for(i in name)print i,number[i],money[i]}' a.txt
zhaoliu 3 11000
zhangsan 2 13000
wangwu 1 1500
lisi 2 3000
20、打印乘法口诀
方法1:
$ awk 'BEGIN{for(n=0;n++<9;){for(i=0;i++<n;)printf i"x"n"="i*n" ";print ""}}'
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81
方法2:
#!/bin/bash
for ((i=1;i<=9;i++)); do
for ((j=1;j<=i;j++)); do
result=$(($i*$j))
#let "result=i*j"
echo -n "$i*$j=$result "
done
echo
done
21、只打印奇数或偶数行
打印奇数行:
方法1:
$ seq 1 5 |awk 'i=!i'
说明:先知道对于数值运算,未定义变量初值为0,对于字符运算,未定义变量初值为空字符串。
读取第一行记录,然后进行模式匹配,i是未定义变量,也就是i=!0,!取反意思。感叹号右边是个布尔值,0或空字符串为假,非0或非空字符串为真,!0就是真,因此i=1,条件为真打印第一条记录。
没有print为什么会打印呢?因为模式后面没有动作,默认会打印整条记录。
读取第二行记录,进行模式匹配,因为上次i的值由0变成了1,此时就是i=!1,条件为假不打印。
读取第三行记录,因为上次条件为假,i恢复初值为0,继续打印。以此类推...
可以看出,运算时并没有判断记录,而是利用布尔值真假判断。
方法2:
$ seq 1 5 |awk 'NR%2!=0'
方法3:
$ seq 1 5 |sed -n '1~2p'
说明:步长,每隔一行打印一次
方法4:
$ seq 1 5 |sed -n 'p;n'
说明:先打印第一行,执行n命令读取当前行的下一行2,放到模式空间,后面再没有打印模式空间行操作,所以只保存不打印,同等方式继续打印第三行。
1
3
5
打印偶数行:
$ seq 1 5 |awk '!(i=!i)'
$ seq 1 5 |awk 'NR%2==0'
$ seq 1 5 |sed -n '0~2p'
$ seq 1 5 |sed -n 'n;p'
awk使用笔记的更多相关文章
- linux awk学习笔记
awk学习笔记 awk语法格式 awk '{pattern + action}' {filenames} awk作用 awk的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后 ...
- 【转】awk学习笔记
Awk学习笔记 整理:Jims of 肥肥世家 <jims.yang@gmail.com> Copyright © 2004 本文遵从GPL协议,欢迎转载.修改.散布. 第一次发布时间:2 ...
- awk 学习笔记
awk的语法有两种形式 awk [options] 'script' var=value file(s) awk [options] -f scriptfile var=value file(s) 选 ...
- sed、grep、awk -- 三剑客笔记记录
sed常用操作笔记 1.删除文件最后一行: sed -i '$d' filename 2.递归替换内容:sed -i 's/内容A/内容B/g' filename sed -i "s/S ...
- sed and awk学习笔记
sed and awk 背景 awk起源追溯至sed和grep,进而追溯至共同的行编辑器ed.实用工具grep来源于ed命令:g/re/p .实用工具awk和sed有一个共同的选项-f用于指定脚本的名 ...
- awk学习笔记二:调用shell、文件执行(转)
awk 'BEGIN {print "Hello"}' 不操作文件直接处理数据流 要调用shell则可以用管道命令 如,打印日期awk 'BEGIN {"date&quo ...
- awk学习笔记一:基础(转)
awk内置变量 ARGC 命令行参数个数ARGV 命令行参数排列ENVIRON 支持队列中系统环境变量的使用FILENAME awk浏览的文件名FNR 浏览文件的记录数FS 设置输入域分隔符,等价于命 ...
- 【转】 awk 学习笔记
本文参考的是 ubuntu 下 gawk version 3.1.6 以及 <sed&awk> 一 . awk 简介 awk 是一种解释型(tawk除外)文本处理语言 二 . aw ...
- AWK读书笔记
1.awk 'parttern {action}' filename 从文件中逐行读取并匹配parttern,若匹配成功执行action否则读取下一行. parttern和action都可选,若省略p ...
- awk练习笔记
题目数据如下: Mike Harrington:(510) 548-1278:250:100:175 Christian Dobbins:(408) 538-2358:155:90:201Susan ...
随机推荐
- java中关键字super
super关键字的作用 java中的super关键字是一个引用变量,用于引用父类对象.关键字“super”以继承的概念出现在类中. 主要用于以下情况:1.调用父类的方法 2.调用父类的变量 3. ...
- 指令——rm
一个完整的指令的标准格式: Linux通用的格式——#指令主体(空格) [选项](空格) [操作对象] 一个指令可以包含多个选项,操作对象也可以是多个. 指令:rm (remove,移除.删除) 作用 ...
- 指令——less
一.Liunx系统下的一般命令格式. 命令——实际上就是在Liunx终端中,在命令行中输入的内容. Liunx中一个命令的完整格式为: #指令主体(空格) [选项](空格) [操作对象] 指令主体—— ...
- 八十七、SAP中ALV事件之一,事件的声明
一.我们双击"REUSE_ALV_GRID_DISPLAY",来到SE37界面, 二,来到这儿,点击SLIS_T_EVENT, 三.可以看到SLIS_T_EVENT的定义,有一个n ...
- 经典SQL50句
50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,T ...
- sed -i添加到第一行
用sed的i\命令在第一行前面插入即可,加上 -i 选项直接操作文件. sed -i '1i\要添加的内容' yourfile 查看插入第一行是否成功 sed -n '1,1p' yourfile
- HDU - 5591 ZYB's Game(博弈)
题意:A和B两人在1~N中选数字.已知1<=X<=N,谁先选中X谁就输.每当一个人选出一个不是X的数,裁判都会说明这个数比X大还是小,与此同时,可选范围随之缩小.已知A先选,求满足能让B赢 ...
- 【shell】常用shell脚本
1.检查主机存活状态 #!/bin/bash IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2" for IP in $IP_LIST; ...
- PHP - 验证码制作加验证
一,主页 index.php <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- OC Swift混编-Swift.h File not found
https://www.jianshu.com/p/f860fe1718ca 2016.09.13 11:53* 字数 266 阅读 1935评论 1喜欢 1 今天碰到个神坑,本人项目是OC项目,最近 ...