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 ...
随机推荐
- plsql调用执行存储过程
参考 https://www.cnblogs.com/enjoyjava/p/9131169.html ------------------------------------------------ ...
- python 鞍点
# 鞍点: 所在行的最大值,所在列的最小值 import random A = [[random.randint(1,100) for j in range(5)]for i in range(5)] ...
- 《学习R》笔记:科学计算器、检查变量和工作区、向量、矩阵和数组、列表和数据框
一.第二章 科学计算器 要检查两个数字是否一样,要使用 all.equal() ,不要使用 == ,== 符号仅用于比较两个整型数是否存在相同 . > all.equal(sqrt(2)^2,2 ...
- 100-PHP二维数组的元素输出三
<?php $stu=array(array(76,87,68), array(65,89,95), array(90,80,66), array(90,95,65)); //定义一个二维数组 ...
- VIJOS-P1282 佳佳的魔法照片 排序
Description 一共有n(n≤20000)个人(以1--n编号)向佳佳要照片,而佳佳只能把照片给其中的k个人.佳佳按照与他们的关系好坏的程度给每个人赋予了一个初始权值W[i].然后将初始权值从 ...
- 可并堆模板题-mergeable heap
Description 有n个点,第i个点标号为i,有两种操作:0 x y 表示把x所在堆和y所在堆合并.1 x 表示询问x所在堆的最小权. Input 第一行两个整数n,m,表示有n个点m个操作. ...
- 51nod 1201:整数划分 超级好的DP题目
1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} { ...
- POJ 1004:Financial Management
Financial Management Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 165062 Accepted: ...
- int *const 与const int *问题
自己一直就不太清楚int *const与const int*之间的差别,总是弄混,今天势必拿一个程序验证一下. 一个指针是有两个属性的,一个是它指向的地方,一个是它指向地方上的内容.两者的差别也在此. ...
- html特殊字符的写法
符号 写法 (空格) <(小于号) < >(大于号) > " " ®(已注册) ® ©(版权) © ™(商标) ™ (半方大的空白) (全方大的空白 ...