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的行

更多参考:

    1.关于 awk 的 pattern(模式) - Shell-Chinaunix

    2.awk--动作(action)_CSDN博客

    3.awk数组操作详细介绍 - 博客园 (cnblogs.com)

posted @ 2021-11-14 23:10  诟笑  阅读(268)  评论(0编辑  收藏  举报