标签:awk 排版 分块操作
awk
流编辑器sed,用于对行进行删除,替换等操作,awk更适合用来排版。
awk工作流程
awk将文本的内容逐行读取到内存中,awk会对读取进内存的行通过某种分隔符(默认为空格\t)进行分块,分块后会对各个块命名
$0-整个行,$1-第一个块,$2-第二个块...$n-第n个块.此时可以指定awk操作的块.同sed一样,awk会通过模式匹配需要操作的
行,不同的是对于未匹配的行,awk会将其忽略。
#ifconfig eth0 | awk ‘/inet addr/{print $2}‘ | awk -F: ‘{print $2}‘
注*
1.awk通过模式/inet addr/匹配特有的行,然后再默认分割符分块的情况下打印第二块.
2.通过指定分割符:将内容分为俩段,打印第二块。
awk的语法
awk [-F] ‘/模式/{命令}‘ file
1.通过模式匹配需要操作的行,未匹配到的行忽略.
2.awk常用于排版,常用的命令为print
3.分割符可加参数F指定
awk中的变量-NF,NR,FNR
1.NF:对读取进内存的行的分块数.
#ifconfig eth0 | awk ‘/inet addr/{print NF}‘
->4
注:在awk中,引用变量不需要加$(除了引用块$n),$NF代表$4
#ifconfig eth0 |awk ‘/inet addr/{print $NF}‘
->mask:255.255.255.0 ----打印第四块
2.NR,FNR
1.对于同一文件而言,NR和FNR代表的都是读取当前操作的行.
2.对于同时操作2个文件时,NR代表读取当前操作的行,而FNR读取的是每个文件操作的当前的行.
demo:存在俩个文件file1,file2.其中file1中有4行,file2中有2行。
#awk ‘{print NR}‘ file1 file2
1
2
3
4
5
6
#awk ‘{print FNR}‘ file1 file2
1
2
3
4
1
2
注:当对多个文件操作时,判断是对哪个文件进行操作,比较NR和FNR的值即可.
在{}执行多条命令时,需要用;号隔开
#ifconfig eth0 | awk ‘{print NR,$2;print NR}‘ -------默认有换行符
在awk中做比较
1.数字比较用到的运算符:==,>=,>,<,<=
2.表示字符串能否匹配上的符号:~
注:比较时,在模式位置数字不必用//环绕,字符串需要用//环绕起来.
#awk -F: ‘$3>=500{print $1}‘ /etc/passwd
->打印/etc/passwd中uid>500的普通用户的用户名
#awk -F: ‘/^root/{print $1}‘ /etc/passwd
->打印/etc/passwd中以root开头的行.
可用&&和||运算符连接多个条件.
#awk -F: ‘$3==0||$3>=500{print $1}‘ /etc/passwd
->打印/etc/passwd中的root用户和普通用户.
对于字符串的比较则是判断字符串能否匹配上
#awk -F: ‘/root/{print }‘ /etc/passwd
#awk -F: ‘$5 ~/root/{print }‘ /etc/passwd
->第一个语句是在文件中搜寻包含root的行打印出来,而第二句则是在文件中按:分割开来,匹配第5部分的root后打印出来.
awk在对文本处理之前可做某些操作,这些操作在BEGIN{}中定义,当awk对文本处理完毕之后可做一些扫尾工作,在END{}中定义.
1.在BEGIN{}中可定义标题及一些变量.
2.定义分割符FS
awk ‘BEGIN{命令1;命令2...}/模式/{命令m;命令n}END{命令x;命令y}‘ file
#awl ‘BEGIN{FS=‘:‘ $5~/root/{print}‘ /etc/passwd
#awk ‘BEGIN{FS=‘:‘ print "用户名"}$3>=500||$3==0{print $1}END{print "end"}‘ /etc/passwd
awk作为和bash一个软件级别,其本身也是一门编程语言,支持高级语言的特性.
1.awk和read读取文件中的行,read只读取一行,读完文本需要利用for循环,awk本身自带循环.
2.awk支持高级编程语言的流程控制,循环语句,函数等功能.
awk支持流程控制if
if语句语法
if(判断){语句1}else if(判断2){语句2}else{语句3}
注:流程控制和循环都需要写入{}中
用if语句实现列出/etc/passwd中不同用户.
awk -F: ‘{if($3==0{print "root usr"} else if($3>=500){print "common usr"} else{print "sys usr"}}‘ /etc/passwd
三目运算符
#awk -F: ‘{print($==0?"root":"not root")}‘ /etc/passwd
awk支持循环语句for-while
while语句语法
while(条件){
语句1
语句2
...
}
demo:将/etc/passwd中root用户行按分隔符分开部分分成不同的行来写.
root:x:0:0:xxxxx:/root/:/bin/bash
root
x
0
0
xxxxx
/root/
/bin/bash
awk -F: ‘$1~/root/{
print "---------------------------------"
i=1
while(i<=NF){print $i ;i++}
}‘ /etc/passwd
当满足某个条件时跳出循环-break
awk -F: ‘{
print "---------------------------------"
i=1
while(i<=NF{
if($1~/shutdown/){break}
print $i,i++}
}‘ /etc/passwd
当遇到next时下面的语句不再执行-next
for循环语法结构
for(i=1;i<n;i++){
语句
}
awk -F: ‘{print "----------------------------"
for(i=1;i<=NF;i++){print $i}
}‘ /etc/passwd
demo:系统内存管理是通过分配页面管理的,对于未写入硬盘的为脏页,反之为干净页.
统计某个进程占用多少脏页,多少干净页
cat /proc/1/smaps | awk ‘/Shard_Clean/{AA +=$2}‘ /Shard_Dirty/{BB +=$2}END{print "clean page:"AA"kb" ;print "dirty pages:"BB"kb" }
awk支持数组,数组定义连续的值,值为元素
1.在awk中,数组的下标不一定非得是数字,所以称散列更合适.
2.在awk中,数组的下标定义为字符串是要用""引起来
定义数组和引用数组
echo ‘‘ | awk ‘{aa[1]=111 aa[2]=222 print aa[1]}‘
echo ‘‘ | awk ‘{aa["a"]=111 aa["b"]=222 print aa["a"]}‘
demo:统计俩个文件中相关联的项目(如统计一个人用身份证办的不同银行卡)
#cat aa
tom:001
bob:002
#cat bb
001:aa
001:bb
002:cc
002:dd
结果集要求
tom:001:aa
tom:001:bb
bob:002:cc
bob:002:dd
现对aa操作用a数组a文件中的值定义数组
aa["$2"]=$0
->可实现
aa[001]=tom:001
aa[002]=bob:002
对bb操作
->此时aa中的$2和bb中的$1是相同的值,引用数组正常
aa[001]=tom:001
aa[002]=bob:002
awk -F: ‘NR==FNR{aa[$2]=$0;next}{print aa[$1":"$2]}‘ aa bb
awk中常用的函数-sub/gsub-length-subsrt
#awk ‘{sub("tom","TOM");print $0}‘ file
#awk ‘{gsub("tom","TOM");print $0}‘ file
demo:系统监控时,利用gnuplot,rrdtool工具需将时间转化为秒数
#LANG=C sar 1 > aa.sar
#date -d ‘12:21:11‘ +%s
length() 计算字符串长度
substr(‘字符串‘,m,n) 从m位置开始截取n个字符串
注* printf 格式化输出
#awk -F ‘/root/{printf "%s %s\n",$1,$5}‘ /etc/passwd
#awk -F ‘/root/{printf "20%s %20s\n"}‘ /etc/passwd
本文出自 “深入决定深度” 博客,请务必保留此出处http://luckye.blog.51cto.com/10890384/1840923
标签:awk 排版 分块操作
原文地址:http://luckye.blog.51cto.com/10890384/1840923