1、awk '/555555*/' test
打印所有包含模式/555555*/的行
2、awk '{print $1}' test
打印文件的第一个字段,字段从行的左端开始,以空白符分隔
3:awk '{print $1,$3}' test
打印文件的第一,第三个字段
4:awk '/555555/{print $1,$3}' test
打印包含模式/555555/的第一,第三个字段
5:
t:制表符,tab键
6.打印数字时,可能需要控制数字的格式。这可以通过printf函数来实现,但是,通过设置一个特殊的awk变量OFMT,使用print函数时也可以控制数字的打印格式。OFMT的默认值时“%.6gd",表示只打印小数部分的前六位。
如果设置了变量OFMT,在打印浮点数时,就只打印小数部分的前两位。百分号表示接下来要定义格式。
BEGIN:必须大写
7:
如果记录的第一个字段的值大于第二个字段的值,则把问号后面那个表达式的值赋给max,否则就将冒号后面的那个表单时的赋给max。
8、
awk的字段分隔 符是冒号;如果字段数(NF)不等于7,则执行接下来的操作块;printf函数打印字符串“line<行号>,does not have 7 fields:”,后面跟上当前记录的记录号(NR)和记录本身($0);如果第一个字段($1)中不含任何字母和数字字符,printf函数就打印字符 串“nonalphanumberic user id:”,后面跟上当前记录的记录号和内容;如果第二个字段是一个星号,就打印字符串“no passwd:",后面跟上记录号和记录本身。
9、用awk命令处理文件"grade.txt":
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
#打印整个文件
zhuyupeng@zhuyupeng-PC ~
$ awk '{print $0}' grade.txt
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
#打印第一和第四个域
zhuyupeng@zhuyupeng-PC ~
$ awk '{print $1,$4}' grade.txt
M.Tansley Green
J.Lulu green
P.Bunny Yellow
J.Troll Brown-3
L.Tansley Brown-2
#打印表头
zhuyupeng@zhuyupeng-PC ~
$ awk 'BEGIN {print "Name Beltn---------------------------"}
> {print $1"t"$4}' grade.txt
Name Belt
---------------------------
M.Tansley Green
J.Lulu green
P.Bunny Yellow
J.Troll Brown-3
L.Tansley Brown-2
附,awk例子解读
awk ' NR < 11 ' #不规范,不建议,浪费时间
awk读取前11行(不包括第11行)。如前所述,这里省略了动作打印输出print。匹配模式是变量NR需要小于11,NR即为当前的行号。这个写法很简单,但是有一个问题,在NR大于10的时候,awk其实还是对每行进行了判断,如果文件很大,比如说有上万行,浪费的时间是无法忽略的。
因此,更好的写法是:
awk '1; NR = 10 { exit }' #我的理解是从第一行开始读数据,将第10行到数据读完后退出。
第一句对当前行进行输出。第二句判断是不是已经到了第10行,如果是则退出。
输出文件的第一行(模拟 head -n filename 将n用1替代 )
awk 'NR > 1 { exit }; 1'
这个例子与前一个很相似,中心思想就是第二行就退出。
输出文件的最后两行(模拟 tail -n filename其中n取值为2 )
awk '{ y=x "n" $0; x=$0}; END { print y }' #效率太低不推荐
第一句总是把一个在当前行前面再加上变量x的内容赋值给y,然后用x记录当前行内容。这样的效果是y的内容始终是上一行 加上当前行的内容。在最后,输出y的内容。如果仔细看的话,不难发现这个写法是很不高效的,因为它不停的进行赋值和字符串连接,只为了找到最后一行!所 以,如果你想要输出文件的最后两行,tail -n 2是最好的选择。
输出文件的最后一行(模拟 tail -n filename 其中n取值为1 )
awk 'END { print }'
句法方面没什么好说的,print省略参数即是等价于print $0。但是这个语句可能不能被非GNU awk的某些awk版本正常执行,如果为了兼容,下面的写法是最安全的:
awk '{ rec = $0 }; END { print rec }' #这个写法更具有兼容性
输出只匹配某些模式的行(模拟 grep )
awk '/regex/'
输出不匹配某些模式的行(模拟 grep -v )
awk '!/regex/'
匹配模式前加“!”就是否定判断结果。
输出匹配模式的行的上一行,而非当前行
awk '/regex/ { print x }; { x = $0 }'
变量x总是用来记录上一行的内容,如果模式匹配了当前行,则输出x的内容。
输出匹配模式的下一行
awk '/regex/ { getline; print }'
这里使用了getline函数取得下一行的内容并输出。getline的作用是将$0的内容置为下一行的内容,并同时更新NR,NF,FNR变量。如果匹配的是最后一行,getline会出错,$0不会被更新,最后一行会被打印。
输出匹配AA 或 BB 或 CC的行
awk '/AA|BB|CC/'
正则表达式。
输出长过65个字符的行
awk 'length > 64'
length([str])返回字符串的长度,如果参数省略,即是以$0作为参数,括号也可以省略了。
输出短于65个字符的行
awk 'length < 65'
和上例基本一样。
输出从匹配行到最后一样的内容
awk '/regex/,0'
这里使用了“pattern1,pattern2”的形式来指定一个匹配的范围,其中pattern2这里为0,也就是false,所以一直会匹配到文件结束。
从第8行输出到第12行
awk 'NR==8,NR==12'
同上例,这也是个范围匹配。
输出第52行
awk 'NR==52' #不建议因为到了第52行awk还会继续往下读取下列的行。
如果想要少执行些不必要的循环,就这样写:
awk 'NR==52 {print;exit}' #建议用这个写法
输出两次正则表达式匹配之间的行
awk '/regex1/, /regex2/'
删除所有的空行
awk NF # NF为真即是非空行。
另外一种写法是用正则表达式:
awk '/./'
这个很类似grep .的思路,但是是不如awk NF好的,因为“.”也是可以匹配空格和TAB的。
打印出空行行号
awk '/^$/{print NR}' filename
同理:打印出含有字符good的行号
awk '/good/{print NR}' filename
打印报告头和结尾 #没有验证,我也没看懂
awk 'BEGIN {print "numAtnumBn------------"} {print $1"t"$2} END {print "ENDAt ENDBn-----------"}' test.txt
numA numB
------------
1 2
3 4
ENDA ENDB
-----------
=============================
< 小于
<= 小于等于
== 等于
!= 不等于
> 大于
>= 大于等于
~ 匹配正则表达式
!~ 不匹配正则表达式
b 退格键
f 走纸换页
n 新行
r 回车键
t tab键 #特别注意这几个红色字体,常用到
ddd 八进制值
c 任意其他特殊字符
例子------------
源文件:
用if判断匹配
用==号匹配——== #一个=是赋值的含义,两个==才是相等表条件
匹配正则
关系匹配:
AND匹配——&&:
或匹配——||:两边任意为真 # 或不是一条竖线也可以吗,疑问?
判断不匹配——! # 感叹号在正则表达式中表示的是非,即否定的含义。
NR 和 NF
NR:记录已读的记录数
NF:浏览记录的域个数
[root@BJIT tmp]# awk '{print NR"t"NF"t"$0}' test.txt # 注意这里到转义字符t表示tab占位符。
1 2 1 a
2 2 3 b
3 2 5 c
4 2 7 a
5 2 9 b
6 2 15 c
[root@BJIT tmp]# awk '{if(NR>0 && $1>7) print $0}' test.txt
9 b
15 c
[root@BJIT tmp]# awk '{if ($1==15)print $NF}' test.txt $NF打印最后域
c # $NF表示的是变量NF的域,即她所对应的$0中最后一个数值。
域值比较(两种方法)
修改数值域取值:
[root@BJIT tmp]# awk '{$1=$1-2;print $1}' test.txt # 将第一列减去2之后在赋值给原来的数值
-1
1
3
5
7
13
[root@BJIT tmp]# awk '{if($1>2)($1="test"); print $0}' test.txt
# 全部输出且如果第一列中有数值大于2,则用test替代。
1 a
test b
test c
test a
test b
test c
[root@BJIT tmp]# awk '{if($1==5){$1="test";print $1}}' test.txt
test
数值相加:
[root@BJIT tmp]# awk '{tot+=$1}; {print $1,$2} END{print tot}' test.txt
# +=是一个正则表达式,再次即tot等于$1列中所有数字之和,因为$1表示的是列,而awk在执行的时候是逐行扫描读取的。 最后END输出这个tot的最终数值。
1 a
3 b
5 c
7 a
9 b
15 c
40
[root@BJIT tmp]# awk '{tot+=$1}; {print $1,$2} END{print tot/100}' test.txt
# 将相加的结果除以100
1 a
3 b
5 c
7 a
9 b
15 c
0.4
替换字符串: (试验中替换成字母不成功)
按照起始位置及长度返回字符串
字符
删掉每行的最后一个字符
源文件:
将其中的空格都以tab键替换