Linux命令-awk命令

awk  擅长处理列 (三剑客老大)一门语言
(空模式、关系运算模式、正则模式、行范围模式、BEGIN/END模式)
NR 代表行号
FNR 各文件分别计数的行号 awk  '{print FNR,$0}' file1 file2
NF 字段数量
FS 指定输入分隔符
OFS 指定输出分隔符
RS 指定输入行分隔符awk -v RS=":" '{print FNR,$0}' /etc/passwd
ORS 指定输出行分隔符
ARGV 表示一个数组,这个数组是命令行所给的参数,如awk 'BEGIN {print ARGV[0],ARGV[1],ARGV[2]}' 1.txt 2.txt
ARGC 表示ARGV里的参数的数量 如awk 'BEGIN {print ARGV[1],ARGC}' 1.txt
-F 指定分隔符
-v FS="|" 跟-F一样,这FS是内置变量
-v OFS="|"
--re-interval和--posix 是用于扩展正则匹配时候用
awk 'NR==31' file.txt ==才是等于,一个=是赋值
awk '{print "\""}'  输出一个双引号
awk '{print "'\''"}'  输出一个单引号
awk '{print "'"$(date)"'"}' 解析变量
awk 'BEGIN{printf "%.2f\n",'$sum' + '$gold'}' 打印变量相加,保留小数位两位
一条统计命令
netstat -antu|awk '{++S[$NF]} END {for (key in S) print key,S[key]}'
netstat -an|awk '/^tcp|udp/ {++S[$NF]} END {for(key in S) print S[key],key}'
例子:
seq 100 >seq.txt
awk '{if(NR>19&&NR<31) print $0}' seq.txt打印20-30行内容
awk 'NR>19 && NR<31' seq.txt打印20-30行内容
awk -F ":" '{OFS=":"}{print $7,$2,$3,$4,$5,$6,$1}' /etc/passwd 注意逗号是打印处理是一个空格,OFS是指定分隔符,好像不需要花括号也行
awk -F ":" '{OFS=":";a=$1;$1=$NF;$NF=a;print}' /etc/passwd
ls|awk '{print "mv",$0,"/tmp"}' |bash查找移动目录
ls -l|awk '{if($2>1) print $0}'查找目录,前提是普通文件没有硬链接
awk -F "|" '{if($1>"2018-07-19 13:00:00") {print $1}}' gold_charge.log  对于时间的判断,时间加双引号
awk -F '|' '{if ($3=='1001') print $0}'
awk '{print NR,$0}' file.txt显示行号
ls -l file.txt |cut -c 2-10|tr "rwx-" "4210"|awk -F "" '{print $1+$2+$3 $4+$5+$6 $7+$8+$9}' 把文件权限变成644显示
        awk '{sum+=$1} END {print "sum=" sum}' file.txt  求和
uptime |awk -F "[, ]+" '{print $(NF-2)}' 查看1分钟负载
awk '{print toupper($0)}' file.txt 把小写字母换成大写字母
awk -F "[/: ]" '{sub(/Apr/,"04");print $1,$2,$3,$4,$5,$6,$7}' file.txt  把/Apr/替换成04
echo "20160421"|awk 'BEGIN{FIELDWIDTHS="4 2 2"}{print $1"-"$2"-"$3}' FIELDWIDTHS指定分割字符数
awk --posix '$1~/^(dns|ssh|http)$/ {print $0}' /etc/services  显示$1以什么开头 --posix 是用作于扩展正则时候
awk -F ":" '$3>15 {b=b+1} END {print b}' /etc/passwd 统计$3>15的数量
awk -F "[,:]" 'OFS="A"{print $4,$12,$8}' monsterDrop.log.2018-05-30|cut -c 1-39|sed -r 's#([0-9]+)A([0-9]+)A([0-9]+)#echo "\1 \2 $(date -d @\3 +"%F %T")"#g'|bash 将时间格式化输出
awk -F "[,:]" '{if($12>0) S[$14]+=$12} END {for(key in S) print key,S[key]}' file.txt  根据$14不同类型来分开累加
awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}' /etc/passwd 在每列最上面添加name,shell最后面添加blue,/bin/nosh
awk '{if(NR==1){print $1;print $2}}' 2.txt 执行多条语句,那么{} 不能省略,单条可以省略
awk -F ":" '{if($3<500){print $1,"系统用户"} else {print $1,"普通用户"}}' /etc/passwd awk中的if..else 只要是注意花括号要带上
awk -v i=1 'BEGIN{while(i<=10){print i;i++}}' while 循环,注意花括号,因为有分号,所以必须要用{}
awk -v i=1 'BEGIN{do{print i;i++}while(i<=10)}' do..while
awk 'BEGIN{for(i=0;i<=10;i++) {print i}}' for循环,注意花括号,因为就一个命令,没有分号,所以花括号省略
awk '{for(i=1;i<=NF;i++){count[$i]++}} END {for(key in count) print key,count[key]}' 3.txt 对每一列都进行遍历统计
awk 'BEGIN{srand();print int(100*rand())}' 生成一个100以内的随机数
#cat 3.txt
2939 2939
2938 987h
2934 2934
2933 2933 2933
2932 2932
2931 9865
2930 2930
2928 2928
2921 9765
awk '{gsub("a","L",$1);print $0}' 3.txt gsub内置函数,$1位置可以替换为$0,或者省略
awk '{gsub("[a-z]","1");print $0}' 3.txt  支持正则,还有一个sub函数,只替换第一次碰到,且只替换一次
awk -F ":" '{$3<500?a++:b++}END {print a,b}' /etc/passwd 三元运算符 条件?表达式1:表达式2
awk ' i=!i' 4.txt 取奇数行,i初始值为0,取反就是i就是真,那么就打印第一行,然后第二行取反就为假,不打印
awk '!(i=!i)' 4.txt 取偶数行
awk-处理文件分组统计,分组求和、取最大最小值,取最大最小记录
一、分组求和并排序
1.存在文件groupsum.txt原始数据如下,对下面的文件根据第四列进行分组,并对1,2,3列进行求和。
0.2  0.3  0.5    1
0.3  0.1   0.2   3
0.4  0.2   0.3   1
0.2  0.2   0.2    2
0.3  0.3   0.3    2
0.3   0.2   0.6   3
0.1   0.1   0.1   4
原始数据如上统计为如下这个样子:
0.6 0.5 0.8 1
0.5 0.5 0.5 2
0.6 0.3 0.8 3
0.1 0.1 0.1 4
实现逻辑:
对每一列简历一个数据,数组下标为第四列的值,当出现重复值时对其进行求和;处理完成之后再END中输出。
实现方法:
awk '{a[$4]+=$1;b[$4]+=$2;c[$4]+=$3}END{for(i in a)print a[i],b[i],c[i],i}' groupsum.txt
对上述文件,根据第四列进行分组,并对1,2,3列进行求和,并根据第四列进行倒叙排列。
awk '{a[$4]+=$1;b[$4]+=$2;c[$4]+=$3}END{for(i in a)print a[i],b[i],c[i],i}' groupsum.txt |sort -k4nr
对上述文件,根据第四列进行分组,并对1,2,3列进行求和,并根据第一列进行倒叙,第二列正序输出。
awk '{a[$4]+=$1;b[$4]+=$2;c[$4]+=$3}END{for(i in a)print a[i],b[i],c[i],i}' groupsum.txt |sort -k1nr -k2n
二、有如下文件,roleid,serverid分组,取出每个角色最后一次登录时的记录
文件last_login 中包含roleid    serverid    logintime    level四个字段,文件具体内容如下:
1001    1    2018-01-01 21:00:02    10
1002    2    2008-01-02 22:01:02    11
1001    1    2018-01-01 20:58:01    9
1001    2    2018-01-01 21:01:02    12
awk -F"\t" '{if($3>a[$1$2]) {a[$1$2]=$3;b[$1$2]=$0}}END{for(i in b) print b[i]}' last_login.txt
三、分组统计
还以last_login.txt 为例,以roleid和serverid分组,统计出现次数。
awk -F "\t" '{a[$1][$2]=a[$1][$2]+1}END{for (i in a) {for (j in a[i]) print i,j,a[i][j]}}' last_login.txt
四、取最后一行
还是以last_login.txt 为例,以roleid和serverid分组,查询每个角色的最后一条记录
awk -F "\t" '{if (a[$1][$2] >$3 ||a[$1][$2]=="") a[$1][$2]=$0}END{for (i in a) {for (j in a[i]) print i,j,a[i][j]}}' last_login.txt
分享到:
关键词:Linux命令

<< 上一篇

Linux命令-sed命令

下一篇 >>

Linux命令-tree命令

网友留言(0 条)

发表评论