awk/gawk 其实就是一种编程语言,作用是对文件中的内容进行扫描和处理
命令格式
awk [options] ‘pattern{action}’ fineName
工作原理
awk在处理文件的时候,是逐行读取文件的内容
当读取一行以后,会检查是否满足指定的条件,如果满条件,则执行响应的动作,如果不满足条件,则继续读取下一行内
容,然后再次判断是否满足条件, 当一个文件中的全部的行都被读取完毕之后,就会自动的退出awk
概念
-
记录(Record):默认文件中的一行就是一个记录(可以修改)
-
字段分隔符(FS Field Separator):用来将一个记录分割成若个字段的那个符号或者字符
-
记录分隔符(RS Record Separator):将一个文件中的全部的内容分给成一个一个记录的那个符号【默认情况下,换行
符就是记录分隔符】
-
字段(Field):记录被分隔符分隔之后的各个区域就是一个一个的字段
-
记录编号(NR Number of Record):awk从文件每读取一行内容,NR都会加
字段的表示方式:
- $1 $2 …
- $0:表示一整条记录
- $NF:表示一条记录的最后一个字段
- $(NF-1):表示倒数第二列
内置变量
NF 字段个数,(读取的列数)
NR 记录数(行号),从1开始,新的文件延续上面的计数,新文件不从1开始
FNR 读取文件的记录数(行号),从1开始,新的文件重新从1开始计数
FS 输入字段分隔符,默认是空格
OFS 输出字段分隔符 默认也是空格
RS 输入行分隔符,默认为换行符
ORS 输出行分隔符,默认为换行符
举例
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
#awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
或
awk -F ':' '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh
awk的一些用法
获取某些列的某些行(打印或不打印第几行)
NR==n 表示打印第n行
NR!=n 表示不打印第n行
1)取test.txt文件中的第1,2列,不打印第一行
[root@bz4citestap1014 app_zhibiao.sh]# cat test.txt
wang 11 aa
shi 22 bb
kevin 33 cc
grace 44 dd
hui 55 ee
[root@bz4citestap1014 app_zhibiao.sh]# awk 'NR!=1 {print $1,$2}' test.txt
shi 22
kevin 33
grace 44
hui 55
2)取test.txt文件中的第3列的第2行
[root@bz4citestap1014 app_zhibiao.sh]# awk 'NR==2 {print $3}' test.txt
bb
统计网站url
#cat /tmp/url.txt
http://www.baidu.com/index.html
http://mail.baidu.com/a.html
http://mail.baidu.com/index.php
http://www.baidu.com/index.asp
http://www.baidu.com/index.jsp
http://ftp.baidu.com/index.cc
http://www.baidu.com/index.html
http://mail.baidu.com/index.htmlx
http://www.baidu.com/index.xml
http://www.baidu.com/index.php
http://mail.baidu.com/index.html
http://www.baidu.com/index.jsp
http://ftp.baidu.com/index.html
http://www.baidu.com/index.asp
http://mail.baidu.com/index.html
http://mail.baidu.com/index.html
http://www.baidu.com/index.html
awk -F "/+" '{url[$2]++}END{for(i in url){print url[i],i}}' /tmp/url.txt
正则表法式补充
1. ^以指定字符为开头
2. $以指定字符为结尾
例子:将以字母i为开头的行的第二个字段输出(要求分隔符为空格)
# awk -F " " '/^i/{print $2}' test.txt
例子:将以字符串conf为结尾的行的第三个字段输出(要求分隔符为/)
# awk -F "/" '/conf$/{print $3}' test.txt
3. .表示任意单个字符
例子:将包含字符串le的行的第二个字段输出(要求分隔符为空格)
# awk -F " " '/le/{print $2}' test.txt
例子:将包含字符串lxxxl的行第二个字段输出(要求分隔符为空格)
# awk -F " " '/l...l/{print $2}' test.txt
4. *表示其前面的字符出现任意次数的情况
例子:将包含字符串WI后面有N多个L的行的第二个字段打印出来(要求分隔符为空格)
# awk -F " " '/WIL*/{print $2}'
补充:
WIL*
W(IL)*
5. +表示其前面的字符出现至少一次的情况
/ro+t/
rot
root
roooot
roooooot
6. ?表示其前面的字符出现最多一次的情况
/ro?t/
rt
rot
7. []匹配范围以内的单个字符
8. [^]匹配范围意外的任意单个字符
例子:将不是以字母S A 或者 # 开的行的第二个字段打印出来(要求分隔符为空格)
# awk -F " " '/^[^SA#]/{print $2}' new.txt
9. ()分组
10. |表示或
例子:将包含字母W或者单词 by的行的第二个字段打印出来(要求分隔符为空格)
# awk -F " " '/W|(by)/{print $2}' new.txt
区分:
W|wc Wc 或者 wc
W|(wc) W 或者 wc
11. {m,n} 表其前面的字符出现至少m次,最多n次的情况
{m} 表示其前面的字符出现m次的情况
{m,}
{,n}
注意:
可以对一整行进行内容匹配筛选,也可以对一个字段进行
如果是对字段进行匹配,需要使用~
例子:将文件以空格为分隔符,输出第三个字段
# awk -F " " '{print $3}' test.txt
例子:将文件以空格为分隔符,将第一个字段中以字母i为开头的行的第三个字段输出
# awk -F " " '$1~/^i/{print $3}'
例子:将文件以空格为分隔符,将第一个字段中不是以字母i为开头的行的第三个字段输出
# awk -F " " '$1!~/^i/{print $3}'
~:判断指定的内容是否满足正则表达式
满足则为真
不满足则为假
!~:判断指定的内容是否不满足正则表达式
不满足则为真
满足则为假