Linux Command awk 文本匹配(1)

简介: Linux Command awk 文本匹配(1)

Linux Command awk 文本匹配

文章目录

Linux Command awk 文本匹配

1. 简介

2. 原理

3. 命令

3.1 awk [选项] '{编辑指令}' 文件

3.2 与管道结合

3.3 awk [选项] '[条件]{编辑指令}' 文件

3.3 awk [选项] ' BEGIN{编辑指令 } {编辑指令} END{编辑指令}' 文件

3.4 第n到末尾参数输出

3.5 多行合并一行

3.6 获取外部变量

3.6.1 获得普通外部变量

3.6.2 BEGIN 获取变量

3.6.3 获取环境变量

3.7 内建变量

3.7.1 FS 指定字段un列分隔符(Font Space)

3.7.2 OFS 指定输出字段列分隔符(Output Font space)

3.7.3 RS 指定行分隔符 默认分隔符为\n(Row Space)

3.7.4 ORS 指定输出行分隔符

3.7.5 RT 代指分隔符

3.7.6 NF 每行字段总数(Number of Font)

3.7.7 NR 当前行数(Number of Row)

4. 脚本

5. 自定义函数

6. 数组

6.1 创建数组

6.2 删除数组元素

6.3 多维数组

7. split 切割

1. 简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。


awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

2. 原理

AWK 工作流程可分为三个部分:

  • 读输入文件之前执行的代码段(由BEGIN关键字标识)。
  • 主循环执行输入文件的代码段。
  • 读输入文件之后的代码段(由END关键字标识)。

命令结构:

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

下面的流程图描述出了 AWK 的工作流程:

1832b220aa754cd18c504acc7686a560.png

1、通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。

2、完成 BEGIN 块的执行,开始执行body块。

3、读入有 \n 换行符分割的记录。

4、将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),1 表 示 第 一 个 域 , 1 表示第一个域,1表示第一个域,n 表示第 n 个域。

5、依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。

6、循环读取并执行各行直到文件结束,完成body块执行。

7、开始 END 块执行,END 块可以输出最终结果。

3. 命令

3.1 awk [选项] ‘{编辑指令}’ 文件

awk '{print $1,$2}' /etc/rc.local      //输出文件的第1、2列
head -7 /etc/passwd > passwd.txt
awk -F ":" '{print $1","$7}' passwd.txt //以“:”作为分隔符,,打印第1和7列
awk -F [:/] '{print $1,$10}' passwd.txt //以“:”或“/”作为分隔符,,打印第1和10列
awk -F: '{print NR,NF}' passwd.txt  // 打印行数与字段数
free | awk '/Mem/{printf("RAM Usage: %.2f\n"), $3/$2*100}'| awk '{print $3}'

3.2 与管道结合

ifconfig eth0 | grep "inet" | awk '{print $2}
df -hT / | tail -1 | awk '{print $6}'
uname -a | awk '{print $1,$3,$12}'      //输出第1、3、12字段
seq 100 | awk 'NR%7==0||NR~/7/{print}'                     #列出100以内整数中7的倍数或是含7的数
seq 100 | awk '$0%7==0||$0~/7/{print}'
行号与每行的实际文本值是一致的,那么根据NR或者$0行值进行判断都是可以的。输出100以内7的倍数或是包含7的数

3.3 awk [选项] ‘[条件]{编辑指令}’ 文件

awk -F: '/bash$/{print}' passwd.txt   #以bash结尾
awk -F: '/^[a-d]/{print $1,$6}' passwd.txt   #以a-d任意字符开头的第1和6列字段打印
awk -F: '/^a|nologin$/{print $1,$7}' passwd.txt  #以a开头或nologin结尾的第1和7列字段打印
awk -F: '$6~/bin$/{print $1,$6}' passwd.txt    #以bin结尾的打印第1和6列
awk -F: '$7!~/nologin$/{print $1,$7}' passwd.txt   #输出其中登录Shell不以nologin结尾(对第7个字段做!~反向匹配)的用户名、登录Shell信息
awk -F: 'NR==3{print}' passwd.txt        #输出第3行(行号NR等于3)的用户记录
awk -F: 'NR%2==1{print}' passwd.txt      #输出奇数行(行号NR除以2余数为1)的用户记录
awk -F: 'NR<=3{print}' passwd.txt        #输出前3行文本
awk -F: 'NR>=5{print}' passwd.txt        #输出从第5行开始到文件末尾的所有行
awk -F: '$1=="sync"{print}' passwd.txt      #输出用户名为“sync”的行
awk -F: '$1==ENVIRON["USER"]{print $1,$6,$7}' passwd.txt  #输出当前用户的用户名、宿主目录、登录Shell信息
awk -F: 'NR>=3&&NR<=5{print}' passwd.txt
awk -F: '(NR>=3)&&(NR<=5){print}' passwd.txt
awk -F: 'NR==3||NR==5{print}' passwd.txt
awk -F: '$7!~/nologin$/||$1~/^[ad]/{print}' passwd.txt  #输出“登录Shell不以nologin结尾”或者“用户名以a或d开头”的文本
awk -F: '$3<3||$3%2==0{print}' passwd.txt    #输出UID小于3或者UID是偶数的用户记录
awk -F: '$3>=501&&$3<=505{print}' /etc/passwd  #输出UID大于501并且小于505的行
awk -F: '/^127|^192/{print}' /etc/hosts   #输出/etc/hosts映射文件内以127或者192开头的记录

3.3 awk [选项] ’ BEGIN{编辑指令 } {编辑指令} END{编辑指令}’ 文件

#打印A乘于2.56的值
awk 'BEGIN{A=1024;print A*2.56}'    
#统计系统中使用bash作为登录Shell的用户总个数
awk 'BEGIN{x=0}/\<bash$/{x++} END{print x}' /etc/passwd    
#输出的内容包括三个部分:列表头、用户信息、列表尾
awk -F: 'BEGIN{print "User\tUID\tHome"} {print $1"\t"$3"\t"$6} END{print "Total "NR" lines."}' /etc/passwd    
#打印行数
awk -F"\t" 'BEGIN{x=0}{x+=NF}END{print x}' /etc/passwd
#以统计passwd.txt文件中以“:”分隔的总字段个数,需要每处理一行时将当前行的字段数(内置变量
awk -F: 'BEGIN{x=0}{x+=NF} END{print "Total "x" fields."}' passwd.txt   
#统计/etc/passwd文件中UID小于或等于500的用户个数
awk -F: 'BEGIN{i=0}{if($3<=500){i++}}END{print i}' /etc/passwd   
#统计/etc/passwd文件中登录Shell是“/bin/bash”的用户个数
awk -F: 'BEGIN{i=0}{if($7~/bash$/){i++}}END{print i}' /etc/passwd 
#统计/etc/passwd文件中登录Shell不是“/bin/bash”的用户个数
awk -F: 'BEGIN{i=0}{if($7!~/bash$/){i++}}END{print i}' /etc/passwd  
#分别统计/etc/passwd文件中UID小于或等于500、UID大于500的用户个数
awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd  
#分别统计/etc/passwd文件中登录Shell是“/bin/bash”、 登录Shell不是“/bin/bash”的用户个数
 awk -F: 'BEGIN{i=0;j=0}{if($7~/bash$/){i++}else{j++}} END{print i,j}' /etc/passwd 
分别统计/etc/passwd文件中登录Shell是“/bin/bash”、“/sbin/nologin”、其他的用户个数
awk -F: 'BEGIN{i=0;j=0;k=0}{if($7~/bash$/){i++} else if($7~/nologin$/){j++}else{k++}}END{print i,j,k}' /etc/passwd
#提取IP地址及访问量
awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log   
#用户登陆次数
who | awk '{IP[$1]++}END{for(i in IP){print i,IP[i]}}' 
列出黑名单)根据此可作防火墙 
awk '{IP[$1]++}END{for(i in IP){print IP[i],i}}' /var/log/httpd/access_log | awk '$1>=500{print $2}' >>ip.log
#对第1)步的结果根据访问量排名
awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log | sort -nr -k 2 
求最大值:
awk 'BEGIN {max = 0} {if ($1+0 > max+0) max=$1} END {print "Max=", max}' test.txt
Max= 118
求最小值:
awk 'BEGIN {min = 65536} {if ($1+0 < min+0) min=$1} END {print "Min=", min}' test.txt
Min= 9
求和:
cat test.txt|awk '{sum+=$1} END {print "Sum= ", sum}'
Sum=  236
求平均值:
cat test.txt|awk '{sum+=$1} END {print "Avg= ", sum/NR}'
Avg=  39.3333

3.4 第n到末尾参数输出

$ echo "1 2 3 4 5" | awk '{for(i=1;i<3;i++)$i="";print}'
  3 4 5
$ echo "1 2 3 4 5" | awk '{$1=$2="";print}'
  3 4 5
$ echo "1 2 3 4 5" | cut -d" " -f3-
3 4 5
$ echo "1 2 3 4 5" | awk '{$1=$2=""}1'
  3 4 5

3.5 多行合并一行

$  cat test
MD_Q9_G1_F
MD_Q9_G1_Ua
MD_Q9_G1_Ub
MD_Q9_G1_Uc
MD_Q9_G1_Uab
MD_Q9_G1_Ubc
MD_Q9_G1_Uca
MD_Q9_G1_Ia
MD_Q9_G1_Ib
MD_Q9_G1_Ic
MD_Q9_G1_Pa
MD_Q9_G1_Pb
MD_Q9_G1_Pc
MD_Q9_G1_Psum
MD_Q9_G1_Qa
MD_Q9_G1_Qb
MD_Q9_G1_Qc
MD_Q9_G1_Qsum
MD_Q9_G1_Sa
MD_Q9_G1_Sb
MD_Q9_G1_Sc
MD_Q9_G1_Ssum
MD_Q9_G1_PFa
MD_Q9_G1_PFb
MD_Q9_G1_PFc
MD_Q9_G1_PF
$ awk '{ORS=NR%50?",":RS}1' test
MD_Q9_G1_F,MD_Q9_G1_Ua,MD_Q9_G1_Ub,MD_Q9_G1_Uc,MD_Q9_G1_Uab,MD_Q9_G1_Ubc,MD_Q9_G1_Uca,MD_Q9_G1_Ia,MD_Q9_G1_Ib,MD_Q9_G1_Ic,MD_Q9_G1_Pa,MD_Q9_G1_Pb,MD_Q9_G1_Pc,MD_Q9_G1_Psum,MD_Q9_G1_Qa,MD_Q9_G1_Qb,MD_Q9_G1_Qc,MD_Q9_G1_Qsum,MD_Q9_G1_Sa,MD_Q9_G1_Sb,MD_Q9_G1_Sc,MD_Q9_G1_Ssum,MD_Q9_G1_PFa,MD_Q9_G1_PFb,MD_Q9_G1_PFc,MD_Q9_G1_PF,
$ awk 'NR%50{printf $0",";next}1'  test
MD_Q9_G1_F,MD_Q9_G1_Ua,MD_Q9_G1_Ub,MD_Q9_G1_Uc,MD_Q9_G1_Uab,MD_Q9_G1_Ubc,MD_Q9_G1_Uca,MD_Q9_G1_Ia,MD_Q9_G1_Ib,MD_Q9_G1_Ic,MD_Q9_G1_Pa,MD_Q9_G1_Pb,MD_Q9_G1_Pc,MD_Q9_G1_Psum,MD_Q9_G1_Qa,MD_Q9_G1_Qb,MD_Q9_G1_Qc,MD_Q9_G1_Qsum,MD_Q9_G1_Sa,MD_Q9_G1_Sb,MD_Q9_G1_Sc,MD_Q9_G1_Ssum,MD_Q9_G1_PFa,MD_Q9_G1_PFb,MD_Q9_G1_PFc,MD_Q9_G1_PF,
awk '{OFS=",";ORS=NR%50?OFS:RS}1' test
MD_Q9_G1_F,MD_Q9_G1_Ua,MD_Q9_G1_Ub,MD_Q9_G1_Uc,MD_Q9_G1_Uab,MD_Q9_G1_Ubc,MD_Q9_G1_Uca,MD_Q9_G1_Ia,MD_Q9_G1_Ib,MD_Q9_G1_Ic,MD_Q9_G1_Pa,MD_Q9_G1_Pb,MD_Q9_G1_Pc,MD_Q9_G1_Psum,MD_Q9_G1_Qa,MD_Q9_G1_Qb,MD_Q9_G1_Qc,MD_Q9_G1_Qsum,MD_Q9_G1_Sa,MD_Q9_G1_Sb,MD_Q9_G1_Sc,MD_Q9_G1_Ssum,MD_Q9_G1_PFa,MD_Q9_G1_PFb,MD_Q9_G1_PFc,MD_Q9_G1_PF,

3.6 获取外部变量

3.6.1 获得普通外部变量

格式:

awk '{action}'  变量名=变量值

这样传入变量,可以在action中获得值。 注意:变量名与值放到’{action}’后面。

$ test='awk code'                           
$ echo | awk  '{print test}' test="$test"
awk code

3.6.2 BEGIN 获取变量

格式:

awk –v 变量名=变量值 [–v 变量2=值2 …] 'BEGIN{action}’

注意:用-v 传入变量可以在3中类型的action 中都可以获得到,但顺序在 action前面。

$ test='awk code'                                
$ echo | awk -v test="$test" 'BEGIN{print test}'
awk code
$ echo | awk -v test="$test" '{print test}'    
awk code
 errnum=$(($errnum+1))
 awk   -F " " -v b="$i" -v d=$errnum '{if ($1==b) $3=d}1{print $0 > "alert_list"}' alert_list

3.6.3 获取环境变量

$ awk  'BEGIN{for (i in ENVIRON) {print i"="ENVIRON[i];}}'
AWKPATH=.:/usr/share/awk
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
LANG=en_US.UTF-8
.......

只需要调用:

awk内置变量 ENVIRON,就可以直接获得环境变量。它是一个字典数组。环境变量名 就是它的键值。

3.7 内建变量

包含:FS,NF,NR,RT,RS,ORS,OFS

3.7.1 FS 指定字段un列分隔符(Font Space)

$ echo "111|222|333" | awk '{print $1}'
111|222|333
$ echo "111|222|333" | awk 'BEGIN{FS="|"}{print $1}'
111

3.7.2 OFS 指定输出字段列分隔符(Output Font space)

$ echo "111 222 333" |awk 'BEGIN{OFS="|";}{print $1,$2,$3}'
111|222|333

3.7.3 RS 指定行分隔符 默认分隔符为\n(Row Space)

$ echo "111 222|333 444|555 666" | awk 'BEGIN{RS="|"}{print $0}'
111 222
333 444
555 666

3.7.4 ORS 指定输出行分隔符

$ awk 'BEGIN{ORS="|";}{print $0;}' test.txt
111 222|333 444|555 666

3.7.5 RT 代指分隔符

$ echo "111 222|333 444|555 666" | awk 'BEGIN{RS="|"}{print $0,RT}'
111 222 |
333 444 |
555 666 |

3.7.6 NF 每行字段总数(Number of Font)

$ cat test.txt
111 222
333 444
555 666
$ awk '{print NF}' test.txt
2
2
2
$ awk '{print $NF}' test.txt
222
444
666

3.7.7 NR 当前行数(Number of Row)

$ cat test.txt
111 222
333 444
555 666 777
$ awk '{print NR}' test.txt
1
2
3
$ awk '{print $NR}' test.txt
111
444
777
相关文章
|
5天前
|
存储 Linux BI
Linux 三剑客 grep、sed、awk
Linux三剑客`grep`、`sed`和`awk`是强大的文本处理工具。`grep`用正则表达式搜索匹配行;`sed`是流式编辑器,处理文本流而不直接修改原文件;`awk`则用于灵活的文本分析和报告生成。例如,`grep`可查找匹配模式,`sed`可以删除文件内容,而`awk`能提取特定字段。通过组合使用,它们能高效解决复杂文本任务。
16 1
|
12天前
|
数据挖掘 Linux Perl
Linux命令join:高效处理文本数据的利器
`join`是Linux文本处理的强兵,用于基于共同字段合并两个已排序文件。它按字典序比较字段,支持自定义分隔符,且能处理未匹配行。`-a`显示未匹配行,`-e`指定空字段替换值,`-j`设置共同字段,`-o`定制输出格式,`-t`定义字段分隔符。在数据分析时,务必先排序文件,并根据需求调整参数。可与`sort`、`cut`等命令配合使用。
|
18天前
|
算法 数据挖掘 Linux
探索Linux中的awk命令:强大的文本分析工具
探索Linux中的`awk`命令,一个强大的文本分析工具,用于模式扫描、数据提取与报告生成。本文介绍`awk`的用途、工作原理、特点及应用示例。`awk`基于&quot;模式-动作&quot;框架,从输入数据中匹配模式并执行相应操作。其特点包括:强大的文本处理能力、灵活的I/O及简洁的语法。示例涵盖了打印特定行、处理字段、计算统计值等场景。使用`awk`时要注意理解输入数据、测试脚本、优化性能和添加注释。深入学习以提升数据处理技能。
|
1月前
|
存储 Linux Shell
Linux|如何在 awk 中使用流控制语句
Linux|如何在 awk 中使用流控制语句
29 1
|
1月前
|
Shell Linux Perl
Linux|如何允许 awk 使用 Shell 变量
Linux|如何允许 awk 使用 Shell 变量
37 2
|
23天前
|
监控 Unix Linux
windows和linux实时监控文本内容的命令
windows和linux实时监控文本内容的命令
25 1
|
23天前
|
数据挖掘 Unix Linux
探索Linux中的强大文本处理工具——dgawk
dgawk,GNU awk的增强版,是一款强大的Linux文本处理工具,擅长模式扫描和数据提取。它提供复杂文本分析、易用性、可定制脚本及高效处理大文件的能力。基本语法为`dgawk &#39;pattern { action }&#39; file`。通过打印、模式匹配、字段操作、BEGIN/END块及自定义函数等功能,用户能高效处理文本数据。掌握dgawk能提升文本分析效率,对系统管理员和数据分析师尤其有用。
|
1月前
|
Linux 开发工具 Perl
|
1月前
|
Linux Perl
Linux|了解如何使用 awk 内置变量
Linux|了解如何使用 awk 内置变量
17 1
|
23天前
|
Linux
探索 Linux 中的 `bzmore` 命令:一个方便的文本查看工具
探索 Linux 中的 `bzmore` 命令:一个方便的文本查看工具