千家信息网

AWK学习笔记

发表于:2024-10-21 作者:千家信息网编辑
千家信息网最后更新 2024年10月21日,学习思路:AWK命令行书写由BEGEN Program END三部分构成BEGEN:在AWK读取输入流文本行处理之前执行,用于初始化变量、定义输出表头信息Program:定义如何处理读的数据,由两部分
千家信息网最后更新 2024年10月21日AWK学习笔记

学习思路:
AWK命令行书写由BEGEN Program END三部分构成

BEGEN:在AWK读取输入流文本行处理之前执行,用于初始化变量、定义输出表头信息Program:定义如何处理读的数据,由两部分构成:pattern{action statements;..},由模式和动作构成,匹配模式则执行动作。END在文件逐行处理完成后执行END语句,用于统计结果、生成报告

处理流程:
AWK将处理对象视为二维表逐行读取逐行处理,默认以空白符作为分隔符(可以使用 -F指定分隔符),将文件内容分隔为多个域(可以理解为列或字段),一行称为一条记录,每条记录由多个字段构成。这些行与列被映射成了AWK的内置变量(可以通过-v选项自定义变量),因此用户就可以通过这些内置变量来定位处理对象中的内容进行处理,简单理解为:基于行读取、基于列进行处理并输出。

语法:

awk [options] 'program' var=value file…

awk [options] -f programfile var=value file…

awk [options] 'BEGIN{action;… }pattern{action;… }END{action;… }' file ...

每个语句块都有

常用选项

-F "分隔符" 用于指定读取输入流文本行中用到的字段分隔符,如果不指则默认以空白符为分隔符,并自动压缩连续的多个空白符视为一个空白符。
-f file 从指定文件中读取通用语句块
-v var=value 用于变量赋值

内置变量:
AWK将处理对象视为二维表逐行读取,逐行处理,一行为一条记录,一列为个字段,行与列被映射成了AWK的内置变量,所以用户才可以像处理二维表格一样处理数据。因此AWK的常用内置变量也就以行和列的维度就进行定义。

行列维度内置变量: AWK将读入的文本行以指定分隔符分割为多个列,分别映射为内置变量$1,$2,$3...$n,即$1代表第1列,$2代表第2列,以此类推。注意:$0代表所有列,如果语句块中没有定义action动作则默认动作为print $0,即打印所有列。

NF:代表被分隔的字段数,即列数NR: 一行为一条记录,行号FNR:AWK可以将多个文件作为输入流,如果希望每个文件分别输出独立的行号则用FNRFILENAME:AWK可以将多个文件作为输入流,如果希望输出行中输出文件名则用FILENAME

分隔符:
AWK处理输入流时可以用-F选项指定分隔符,但一定会满足用户的使用需求,例:在打印输出时,打印输入时用的分隔符,就需要手动指定很麻烦,AWK同样想到了用户的这一需求,提供了分隔符相关的内置变量。AWK的处理流程就是输入流处理后生成输出流,所以分隔符也就有了输入分隔符、输出分隔符。

记住几个单词:F:Field S:Separated O:output R:recordFS:输入分隔符OFS:输出分隔符RS:输入记录分隔符ORS:输出记录分隔符FNR:各文件分别计数,记录号FILENAME:当前文件名

其它变量
ARGC:命令行参数的个数
ARGV:数组,保存的是命令行所给定的各参数

自定义变量
自定义变量一般用于数据辅助处理(如控制语句),报表输出美化等。自定义变量有两种定义方式:

  1. -v选项定义:
  2. 无事先声明,直接写在program语句块中。

格式化输出
AWK的强项就是报表输出功能,printf命令可以对处理后的数据进行格式化输出,起到美化报表的效果。在格式化输出过程中要注意以下几点:

  1. 必须指定FORMA
  2. 不会自动换行,需要显式给出换行控制符\n
  3. FORMAT中需要分别为后面每个item指定格式符

格式符

  1. %c:显示字符的ASCII码
  2. %d, %i:显示十进制整数
  3. %e, %E:显示科学计数法数值
  4. %f:显示为浮点数
  5. %g, %G:以科学计数法或浮点形式显示数值
  6. %s:显示字符串
  7. %u:无符号整数
  8. %%:显示%自身

修饰符

  1. #[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
  2. -左对齐(默认右对齐) %-15s
  3. +显示数值的正负符号 %+d

例:

  1. 指定输出$1对应的输出修饰为左对齐,输出域宽度为20个字符,$3输出域宽度为10个字符,并换行

    awk -F: '{printf "%-20s d\n",$1,$3}' /etc/passwd

  2. 指定Username:之后输出$1,格式为左对齐,输出域宽度为15个字符,UID:之后输出$3

    awk -F: '{printf "Username: %-15s,UID:%d\n",$1,$3}' /etc/passwd


AWK中的操作符

1. 算术操作符

注意:算术运行表达式输写时变量不需要加$符号引用,直接输写

x+y, x-y, x*y, x/y, x^y, x%y-x:转换为负数+x:将字符串转换为数值

2. 赋值操作符

注意:要注意在输写自加自减赋值表达式时,i++与++i的区别

=, +=, -=, *=, /=, %=, ^=,++, --i++ 先赋值,再自加,例在循环语句中i=0,A=i++,则A的结果为0,i的结果为1++i 先自加,再赋值,例在循环语句中i=0,A=++i,则A的结果为1,i的结果为1

3. 比较操作符

注意:在应用的时候需要注意==与=的输写,有时候疏忽可能会出现书写错误。

==, !=, >, >=, <, <=

例:显示$3字段等于0的行

[root@Centos8 ~]#awk -F: '$3==0{print $1,$3}' /etc/passwd

4. 模式匹配符

~:左边是否和右边匹配,意为:包含!~:是否不匹配 意为:不包含

例:

awk '$1 ~ "^root"' /etc/passwd 文件中第一字段是否包含rootawk '$0 !~ /root/' /etc/passwd 文件不包含root的行

5. 逻辑操作符

与:&& 意为:并且或:|| 意为:或者非:!  意为:取反

例:基于UID过滤显示用户

awk -F: '$3>=0 && $3 <=500{print $1,$3}' /etc/passwdawk -F: '$3==0 || $3>=1000 {print $1},$3' /etc/passwdawk -F: '!($3>=500) {print $1,$3}' /etc/passwd

6.条件表达式(三目表达式)

语法:selector?if-true-expression:if-false-expression

selector:判断条件if-true-expression:如果为真则执行该语句if-false-expression:如果为假则为执行该语句

例:条件赋值

awk -F: '$3>=1000?usertype="common user":usertype="sysuser";prin $1,$3' /etc/passwd

AWK中的模式

从输入流中读取行,并基于模式匹配,如果满足条件则执行相应的处理。

空模式:如果未指定:匹配每一行正则表达式:/regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来关系表达式:结果为"真"才会被处理,非0非空即为真。行范围匹配:起始位置,结束位置;/pattern1/,/pattern2/ 不支持直接给出数字格式,pattern可以是正则表达式BEGIN/END模式:

例:
匹配以root开头的行到以nobody开头的行之间的所有行
awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd


控制语句

AWK中控制语名输写原则:

1. 控制语句通体被大括号{}包裹2. 判断条件由小括号()包裹3. action作为控制语句了执行语句块,为了逻辑清晰建议action由{}包裹

1. if条件判断

语法1:if与else分体输写,用分号分隔:

'{if(condition) {statements;…};else {statements;…}}' if与else用分号分隔,然后整个语块被{}包裹

例:awk -F: '{if($3>=1000){print "common:",$1} else {print "sysuser:",$1}}' /etc/passwd

语法2:if与else合体输写,不用分号分隔

'{if(condition) {statements;…} else {statements;…}}' if与else不用分号分隔,然后整个语块被{}包裹

例:awk -F: '{if($3>=1000) {print "Common user:",$1} else {print "root or Sysuser:",$1}}' /etc/passwd

语法3:if嵌套

'{if(condition) {statements;…} else if(condition) {statements;…}else {statements;…}}''{if(condition) action...;else if(condition) action...;else action...}' if else语句块之间用分号分隔

例:awk 'BEGIN{test=100;if(test>90){print "very good"} else if(test>60){ print "good"}else{print "no pass"}}'

例:awk 'BEGIN{test=10;if(test>80)print "very Good";else if(test>60)print "Good";else print "no pass"}'

2. for循环

for(expr1;expr2;expr3) {statements;…}

例:awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

3. while循环

语法:while(conditon) {statments;…}

例:awk '/^[[:space:]]linux16/{i=1;while(i<=NF){print $i,length($i); i++}}' /etc/grub2.cfg
例:awk '/^[[:space:]]
linux16/{i=1;while(i<=NF){if(length($i)>=10){print $i,length($i)}; i++}}' /etc/grub2.cfg

4. do...while

do...while与while的区别:do...while雁过拔毛不管条件满不满足至少执行一次;while在条件不满足时可以一次都不执行

语法:do {statements;…} while(condition)

例:awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}'

输出 处理 分隔符 变量 语句 文件 输入 条件 模式 字段 格式 表达式 语法 控制 多个 字符 结果 分号 包裹 意为 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络技术咨询服务合同 越海扬波服务器 万方数据库的概念 服务器有放射线吗 网络安全相关法律条例 联想服务器r2292灯长闪 神赞网络技术 虹口区网络技术哪家好 广东省初越网络技术有限公司 软件开发技术经理年终总结 株洲县嵌入式软件开发 信息系统网络安全检查报告 服务器连接本地打印机 在修改某个数据库对象之前的设计 什么是数据库防火墙 网络安全专干考什么科目 网络安全民宗局应急预案 松江区服务器回收哪里有 psp个体软件开发过程 coc 分服务器 中信银行软件开发公司 哪种品牌的网络安全型号 深圳口碑好的网络技术服务电话 安徽网络安全非标机箱制造厂 支付宝软件开发人是谁 福建潮流软件开发设施有哪些 上海手机软件开发大概多少钱 以科技改变为推动点以互联网 什么是全球互联网网络技术 深圳爱康生物有限公司软件开发
0