day7:awk命令入门
awk 是一种用于处理文本的工具。
awk提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。
awk工作原理:
awk 会把每行按照分隔符进行拆分,用相应的命令对拆分出来的“列”进行处理。
(1)行工作模式,读入文件的每一行,会把一行的内容,存到$0里
(2)使用内置的变量FS(段的分隔符,默认用的是空白字符),分割这一行,把分割出来的每'列'存到相应的变量$(1-100)
(3)输出的时候按照内置变量OFS(out FS),输出
(4)读入下一行继续操作
awk语法:
awk [options] 'pattern' filename
awk [options] '{action}' filename
awk [options] 'pattern {action}' filename
关于awk中的pattern 或者 action 文末有对应的文章链接
options常用选项:
-F fs or --field-separator fs
指定输入文件折分隔符(默认是空格),fs是一个字符串或者是一个正则表达式,如-F:。
-v var=value or --asign var=value
赋值一个用户定义变量;
awk对整列进行加减: awk -va=1 '{print $1,$1+a}' filename 表示输出指定文件的第一列及将第一列加1后的结果(前提是$1这一列是数字才能成功相加)
awk对整列添加前后缀:awk -F: -va=用户名是 '{print a$1}' /etc/passwd 表示输出以:为分隔符的指定文件的第一列并在第一列前统一加上"用户名是"
-V
查看当前awk版本
awk常用内置变量:
变量 | 描述 |
---|---|
$n | 当前记录的第n个字段,字段间由FS分隔 |
$0 | 完整的输入记录 |
ARGC | 命令行参数的数目 |
ARGIND | 命令行中当前文件的位置(从0开始算) |
ARGV | 包含命令行参数的数组 |
CONVFMT | 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组 |
ERRNO | 最后一个系统错误的描述 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔) |
FILENAME | 当前文件名 |
FNR | 各文件分别计数的行号 |
FS | 字段分隔符(默认是空格)(和-F选项一个效果) |
IGNORECASE | 如果为真,则进行忽略大小写的匹配 |
NF | 一条记录的字段的数目(即一行有几列,默认每列以空格分隔) |
NR | 已经读出的记录数,就是行号,从1开始 |
OFMT | 数字的输出格式(默认值是%.6g) |
OFS | 输出字段分隔符,默认值与输入字段分隔符一致。 |
ORS | 输出记录分隔符(默认值是一个换行符) |
RLENGTH | 由match函数所匹配的字符串的长度 |
RS | 记录分隔符(默认是一个换行符) |
RSTART | 由match函数所匹配的字符串的第一个位置 |
SUBSEP | 数组下标分隔符(默认值是/034) |
eg1:
awk -F: ‘NR==2{print $1}’ filename 以:为分隔符打印文件指定行列(第二行第一列)内容,可以打印/etc/passwd查看效果
awk的action主要包含两类:
1.常规的表达式:包含设置常量,变量,赋值, 函数调用(包含 print,printf 和 自定义函数)
2.流程,如if、while、for等
awk内置函数:
linux awk 内置函数详细介绍(实例) - 博客园 (cnblogs.com)
awk中条件判断的应用:
awk [options] '[condition]{action}' filename
condition可以是正则表达式、数值/字符比较以及逻辑比较
符号 | 含义 |
== | 等于 |
!= | 不等于 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
|| | 或 |
&& | 与 |
数字/字符比较eg: awk -F: '$1=="root"{print $0}' /etc/passwd 打印/etc/passwd文件以:分隔的第一列等于root的行
ps: 如果是比较数字,如$1==11,则也会匹配到011,也最好以匹配字符的方式("11")来匹配;
eg2:统计当前目录下的文件个数、目录个数及其它类型的数量
ls -l | awk '{if($1~/^-/){f++}else if($1~/^d/){d++}else{o++}}END{print "文件个数:"f, "目录个数:"d, "其他:"o}'
awk中的BEGIN、END:
BEGIN和END是特殊的pattern
awk [options] 'BEGIN{action}{action}END{action}' filename
BEGIN:BEGIN{}中的action是在awk开始扫描输入的内容前执行,一般用来初始化或设置全局变量;只使用BEGIN可以不需要操作文件(eg: awk 'BEGIN{a=234567891;print a}' )。
END:END{}中的action是在awk处理完内容、在退出之前执行。
eg: 统计/etc/passwd文件中以r或s开头的行数
awk 'BEGIN{n=0}/^[rs]/{n++}END{print n}' /etc/passwd
awk中正则表达式的应用:
正则表达式放在哪?
根据开篇语法格式可知,正则表达式应该放在‘pattern’这个位置。
awk如何处理正则表达式
在awk目录中,正则表达式是置于两个单斜线【/】之间、由字符组成的模式。如果输入行中的某个字符串与正则表达式相匹配,则最终条件为真,于是执行与该表达式关联的所有操作。
如果没有指定操作,则打印与正则表达式匹配的整行记录;
eg1:awk '/nologin$/' /etc/passwd 表示打印以nologin结尾的行
eg2:ls -l | awk '/^d/' 打印当前路径下的文件夹
在awk中还有列的概念,因此也可以根据列来进行匹配:
eg: awk -F: '$7!~/bash$/{print $7}' /etc/passwd
表示以:为分隔符打印/etc/passwd文件中第7列不是以bash结尾的第7列 $7!~/bash$/表示不匹配第7列以bash结尾,也可以写成awk -F: '{if($7!~/bash$/)print $7}' /etc/passwd
在正则表达式单斜线(/bash$/)前,添加~符号表示匹配后面正则表达式;添加!~表示不匹配正则表达式
更多元字符如下:
元字符 | 功能 | 示例 |
^ | 行首定位符 | /^my/ 匹配所有以my开头的行 |
$ | 行尾定位符 | /my$/ 匹配所有以my结尾的行 |
. | 匹配除换行符以外的单个字符 | /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行 |
* | 匹配零个或多个前导字符 | /my*/ 匹配包含字母m,后跟零个或多个y字母的行 |
[] | 匹配指定字符组内的任一字符 | /[Mm]y/ 匹配包含My或my的行 |
[^] | 匹配不在指定字符组内的任一字符 | /[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行 |
保存已匹配的字符 | 1,20s/self/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。 | |
& | 保存查找串以便在替换串中引用 | s/my/**&**/ 符号&代表查找串。my将被替换为**my** |
\< | 词首定位符 | /\<my/ 匹配包含以my开头的单词的行 |
\> | 词尾定位符 | /my\>/ 匹配包含以my结尾的单词的行 |
x\{m\} | 连续m个x | /9\{5\}/ 匹配包含连续5个9的行 |
x\{m,\} | 至少m个x | /9\{5,\}/ 匹配包含至少连续5个9的行 |
x\{m,n\} | 至少m个,但不超过n个x | /9\{5,7\}/ 匹配包含连续5到7个9的行 |