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
相关文章
|
3月前
|
Linux Perl
在Linux中,如何使用请用 cut 或者 awk,sed命令取出 linux 中 eth0 的 IP 地址?
在Linux中,如何使用请用 cut 或者 awk,sed命令取出 linux 中 eth0 的 IP 地址?
|
13天前
|
Linux 开发工具
linux文本管理命令
本文档介绍了Linux系统中常用的文本处理命令,包括`echo`、`cat`、`head`、`tail`、`wc`、`less`、`grep`以及重定向符号的使用方法和练习题。此外,还详细讲解了VIM编辑器的特点、工作模式、常用快捷键和高级技巧,帮助用户高效地进行文本编辑和处理。
28 4
|
26天前
|
Linux Perl
Linux awk命令使用技巧
【10月更文挑战第16天】Linux awk命令使用技巧
27 4
|
1月前
|
存储 安全 Linux
Linux文件管理命令md5sum awk
通过结合 `md5sum`和 `awk`,不仅可以高效地进行文件完整性校验,还能灵活地处理和分析校验结果,为系统管理、数据审计等工作提供强大的支持。
54 2
|
2月前
|
Linux Shell
10-10|linux命令查询 关键字在文本中出现的行数
10-10|linux命令查询 关键字在文本中出现的行数
|
3月前
|
Linux
Linux 系列之 在一个文本中查找指定的数据
文章介绍了在Linux命令行中使用文本搜索功能快速查找指定内容的方法,并提供了按`n`键查找下一个匹配项的技巧。
Linux 系列之 在一个文本中查找指定的数据
|
3月前
|
Linux 数据处理 Perl
在Linux中,awk命令的如何使用?
在Linux中,awk命令的如何使用?
|
3月前
|
数据挖掘 Linux Perl
在Linux中,awk和sed命令的作用?
在Linux中,awk和sed命令的作用?
|
3月前
|
Linux
在Linux中,如何使用grep命令搜索文本?
在Linux中,如何使用grep命令搜索文本?
|
3月前
|
Linux BI 数据处理
在Linux中,如何使用awk和sed进行文本处理?
在Linux中,如何使用awk和sed进行文本处理?