linux awk命令详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
awk 是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
awk 处理过程: 依次对每一行进行处理,然后输出
awk 命令形式:
awk  [-F|-f|- v ] ‘BEGIN{}  // {command1; command2} END{}’  file
  [-F|-f|- v ]   大参数,-F指定分隔符,-f调用脚本,- v 定义变量 var=value
'  '           引用代码块
BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
//            匹配代码块,可以是字符串或正则表达式
{}           命令代码块,包含一条或多条命令
;          多条命令使用分号分隔
END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
  
特殊要点:
$0           表示整个当前行
$1           每行第一个字段
NF          字段数量变量
NR          每行的记录号,多文件记录递增
FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始
\t            制表符
\n           换行符
FS          BEGIN时定义分隔符
RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~            匹配,与==相比不是精确比较
!~           不匹配,不精确比较
==         等于,必须全部相等,精确比较
!=           不等于,精确比较
&&      逻辑与
||             逻辑或
+            匹配时表示1个或1个以上
/[0-9][0-9]+/   两个或两个以上数字
/[0-9][0-9]*/    一个或一个以上数字
FILENAME 文件名
OFS      输出字段分隔符, 默认也是空格,可以改为制表符等
ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F '[:#/]'    定义三个分隔符
  
print & $0
print 是 awk 打印指定内容的主要命令
awk  '{print}'   /etc/passwd    ==    awk  '{print $0}'   /etc/passwd  
awk  '{print " "}'  /etc/passwd                                            // 不输出 passwd 的内容,而是输出相同个数的空行,进一步解释了 awk 是一行一行处理文本
awk  '{print "a"}'    /etc/passwd                                         // 输出相同个数的a行,一行只有一个a字母
awk  -F ":"  '{print $1}'   /etc/passwd 
awk  -F:  '{print $1; print $2}'    /etc/passwd                    // 将每一行的前二个字段,分行输出,进一步理解一行一行处理文本
awk   -F:  '{print $1,$3,$6}'  OFS= "\t"  /etc/passwd         // 输出字段1,3,6,以制表符作为分隔符
  
-f指定脚本文件
awk  -f script. awk   file
BEGIN{
FS= ":"
}
{print $1}                // 效果与 awk  -F ":"  '{print $1}' 相同,只是分隔符使用FS在代码自身中指定
  
awk  'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}'  test 
find  4 blank lines.
  ls  -l| awk  'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'                     // 计算文件大小
total size is 17487
  
-F指定分隔符
$1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符
一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格
awk  -F ":"  '{print $1}'   /etc/passwd
awk  -F ":"  '{print $1 $3}'   /etc/passwd                        // $1与$3相连输出,不分隔
awk  -F ":"  '{print $1,$3}'   /etc/passwd                        // 多了一个逗号,$1与$3使用空格分隔
awk  -F ":"  '{print $1 " " $3}'   /etc/passwd                   // $1与$3之间手动添加空格分隔
awk  -F ":"  '{print "Username:" $1 "\t\t Uid:" $3 }'  /etc/passwd        // 自定义输出  
awk  -F:  '{print NF}'  /etc/passwd                                 // 显示每行有多少字段
awk  -F:  '{print $NF}'  /etc/passwd                               // 将每行第NF个字段的值打印出来
  awk  -F:  'NF==4 {print }'  /etc/passwd                        // 显示只有4个字段的行
awk  -F:  'NF>2{print $0}'  /etc/passwd                        // 显示每行字段数量大于2的行
awk  '{print NR,$0}'  /etc/passwd                                  // 输出每行的行号
awk  -F:  '{print NR,NF,$NF,"\t",$0}'  /etc/passwd       // 依次打印行号,字段数,最后字段值,制表符,每行内容
awk  -F:  'NR==5{print}'   /etc/passwd                          // 显示第5行
awk  -F:  'NR==5 || NR==6{print}'   /etc/passwd        // 显示第5行和第6行
route -n| awk  'NR!=1{print}'                                        // 不显示第一行
  
// 匹配代码块
// 纯字符匹配   ! // 纯字符不匹配   ~ // 字段值匹配    !~ // 字段值不匹配   ~ /a1 |a2/字段值匹配a1或a2   
awk  '/mysql/'  /etc/passwd
awk  '/mysql/{print }'  /etc/passwd
awk  '/mysql/{print $0}'  /etc/passwd                    // 三条指令结果一样
awk  '!/mysql/{print $0}'  /etc/passwd                   // 输出不匹配mysql的行
awk  '/mysql|mail/{print}'  /etc/passwd
awk  '!/mysql|mail/{print}'  /etc/passwd
awk  -F:  '/mail/,/mysql/{print}'  /etc/passwd          // 区间匹配
awk  '/[2][7][7]*/{print $0}'  /etc/passwd                // 匹配包含27为数字开头的行,如27,277,2777...
awk  -F:  '$1~/mail/{print $1}'  /etc/passwd            // $1匹配指定内容才显示
awk  -F:  '{if($1~/mail/) print $1}'  /etc/passwd      // 与上面相同
awk  -F:  '$1!~/mail/{print $1}'  /etc/passwd           // 不匹配
awk  -F:  '$1!~/mail|mysql/{print $1}'  /etc/passwd        
  
IF语句
必须用在{}中,且比较内容用()扩起来
awk  -F:  '{if($1~/mail/) print $1}'  /etc/passwd                                        // 简写
awk  -F:  '{if($1~/mail/) {print $1}}'   /etc/passwd                                    // 全写
awk  -F:  '{if($1~/mail/) {print $1} else {print $2}}'  /etc/passwd             //if ... else ...
  
  
条件表达式
==   !=   >   >=  
awk  -F ":"  '$1=="mysql"{print $3}'  /etc/passwd  
awk  -F ":"  '{if($1=="mysql") print $3}'  /etc/passwd           // 与上面相同 
awk  -F ":"  '$1!="mysql"{print $3}'  /etc/passwd                  // 不等于
awk  -F ":"  '$3>1000{print $3}'  /etc/passwd                       // 大于
awk  -F ":"  '$3>=100{print $3}'  /etc/passwd                      // 大于等于
awk  -F ":"  '$3<1{print $3}'  /etc/passwd                             // 小于
awk  -F ":"  '$3<=1{print $3}'  /etc/passwd                          // 小于等于
  
逻辑运算符
&& || 
awk  -F:  '$1~/mail/ && $3>8 {print }'  /etc/passwd          // 逻辑与,$1匹配mail,并且$3>8
awk  -F:  '{if($1~/mail/ && $3>8) print }'  /etc/passwd
awk  -F:  '$1~/mail/ || $3>1000 {print }'  /etc/passwd        // 逻辑或
awk  -F:  '{if($1~/mail/ || $3>1000) print }'  /etc/passwd 
  
数值运算
awk  -F:  '$3 > 100'  /etc/passwd    
awk  -F:  '$3 > 100 || $3 < 5'  /etc/passwd  
awk  -F:  '$3+$4 > 200'  /etc/passwd
awk  -F:  '/mysql|mail/{print $3+10}'  /etc/passwd                     // 第三个字段加10打印 
awk  -F:  '/mysql/{print $3-$4}'  /etc/passwd                              // 减法
awk  -F:  '/mysql/{print $3*$4}'  /etc/passwd                              // 求乘积
awk  '/MemFree/{print $2/1024}'  /proc/meminfo                   // 除法
awk  '/MemFree/{print int($2/1024)}'  /proc/meminfo            // 取整
  
输出分隔符OFS
awk  '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}'  OFS= "\t"  netstat .txt
awk  '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}'  OFS= "\t"  netstat .txt        
// 输出字段6匹配WAIT的行,其中输出每行行号,字段4,5,6,并使用制表符分割字段
  
输出处理结果到文件
①在命令代码块中直接输出    route -n| awk  'NR!=1{print > "./fs"}'   
②使用重定向进行输出           route -n| awk  'NR!=1{print}'   > . /fs
  
格式化输出
netstat  -anp| awk  '{printf "%-8s %-8s %-10s\n",$1,$2,$3}' 
printf 表示格式输出
%格式化输出分隔符
-8长度为8个字符
s表示字符串类型
打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),
第三个字段输出字符串类型(长度为10)
netstat  -anp| awk  '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'
netstat  -anp| awk  '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'
  
IF语句
awk  -F:  '{if($3>100) print "large"; else print "small"}'  /etc/passwd
small
small
small
large
small
small
awk  -F:  'BEGIN{A=0;B=0} {if($3>100) {A++; print "large"} else {B++; print "small"}} END{print A,"\t",B}'  /etc/passwd 
                                                                                                                  
  //ID 大于100,A加1,否则B加1
awk  -F:  '{if($3<100) next; else print}'  /etc/passwd                          // 小于100跳过,否则显示
awk  -F:  'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }'  /etc/passwd   
awk  -F:  'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }'  /etc/passwd
另一种形式
awk  -F:  '{print ($3>100 ? "yes":"no")}'   /etc/passwd 
awk  -F:  '{print ($3>100 ? $3":\tyes":$3":\tno")}'   /etc/passwd
  
while 语句
awk  -F:  'BEGIN{i=1} {while(i<NF) print NF,$i,i++}'  /etc/passwd 
7 root 1
7 x 2
7 0 3
7 0 4
7 root 5
/root  6
  
数组
netstat  -anp| awk  'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'
netstat  -anp| awk  'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'
9523                               1     
9929                               1     
LISTEN                            6     
7903                               1     
3038 /cupsd                    1     
7913                               1     
10837                             1     
9833                               1     
  
应用1
awk  -F:  '{print NF}'  helloworld.sh                                                        // 输出文件每行有多少字段
awk  -F:  '{print $1,$2,$3,$4,$5}'  helloworld.sh                                  // 输出前5个字段
awk  -F:  '{print $1,$2,$3,$4,$5}'  OFS= '\t'  helloworld.sh                  // 输出前5个字段并使用制表符分隔输出
awk  -F:  '{print NR,$1,$2,$3,$4,$5}'  OFS= '\t'  helloworld.sh            // 制表符分隔输出前5个字段,并打印行号
  
应用2
awk  -F '[:#]'  '{print NF}'   helloworld.sh                                                   // 指定多个分隔符: #,输出每行多少字段
awk  -F '[:#]'  '{print $1,$2,$3,$4,$5,$6,$7}'  OFS= '\t'  helloworld.sh    // 制表符分隔输出多字段
  
应用3
awk  -F '[:#/]'  '{print NF}'  helloworld.sh                                                // 指定三个分隔符,并输出每行字段数
awk  -F '[:#/]'  '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}'  helloworld.sh      // 制表符分隔输出多字段
  
应用4
计算 /home 目录下,普通文件的大小,使用KB作为单位
ls  -l| awk  'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'
ls  -l| awk  'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}'          //int 是取整的意思
  
应用5
统计 netstat  -anp 状态为LISTEN和CONNECT的连接数量分别是多少
netstat  -anp| awk  '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'
  
应用6
统计 /home 目录下不同用户的普通文件的总数是多少?
ls  -l| awk  'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'   
mysql        199 
root           374 
统计 /home 目录下不同用户的普通文件的大小总size是多少?
ls  -l| awk  'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}'
  
应用7
输出成绩表
awk  'BEGIN{math=0;eng=0;com=0; printf  "Lineno.   Name    No.  
   Math   English   Computer    Total\n"; printf 
"------------------------------------------------------------\n" }{math+=$3;
  eng+=$4; com+=$5; printf  "%-8s %-7s %-7s %-7s %-9s %-10s %-7s 
\n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{ printf 
"------------------------------------------------------------\n" ; printf 
"%-24s %-7s %-9s %-20s \n" , "Total:" ,math,eng,com; printf  "%-24s %-7s %-9s
  %-20s \n "," Avg:",math /NR ,eng /NR ,com /NR }' test0
 
[root@localhost home] # cat test0 
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

wKiom1mRamDB54qHAABJorQ2598277.jpg















本文转自leonardos51CTO博客,原文链接:http://blog.51cto.com/leomars/1956197 ,如需转载请自行联系原作者



相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
0
0
0
143
分享
相关文章
|
1天前
|
Linux 常用文件查看命令
`cat` 命令用于连接文件并打印到标准输出,适用于快速查看和合并文本文件内容。常用示例包括:`cat file1.txt` 查看单个文件,`cat file1.txt file2.txt` 合并多个文件,`cat &gt; filename` 创建新文件,`cat &gt;&gt; filename` 追加内容。`more` 和 `less` 命令用于分页查看文件,`tail` 命令则用于查看文件末尾内容,支持实时追踪日志更新,如 `tail -f file.log`。
20 5
Linux 常用文件查看命令
|
7天前
|
Linux od命令
本文详细介绍了Linux中的 `od`命令,包括其基本语法、常用选项和示例。通过这些内容,你可以灵活地使用 `od`命令查看文件内容,提高分析和调试效率。确保理解每一个选项和示例的实现细节,应用到实际工作中时能有效地处理各种文件查看需求。
43 19
|
17天前
|
Linux查看内存命令
1. free free命令是最常用的查看内存使用情况的命令。它显示系统的总内存、已使用内存、空闲内存和交换内存的总量。 free -h • -h 选项:以易读的格式(如GB、MB)显示内存大小。 输出示例: total used free shared buff/cache available Mem: 15Gi 4.7Gi 4.1Gi 288Mi 6.6Gi 9.9Gi Swap: 2.0Gi 0B 2.0Gi • to
30 2
|
18天前
|
Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget
通过本文,我们详细了解了 `yum`、`rpm`、`apt-get`和 `wget`的区别、常用命令以及在CentOS和Ubuntu中安装 `wget`的方法。`yum`和 `apt-get`是高层次的包管理器,分别用于RPM系和Debian系发行版,能够自动解决依赖问题;而 `rpm`是低层次的包管理工具,适合处理单个包;`wget`则是一个功能强大的下载工具,适用于各种下载任务。在实际使用中,根据系统类型和任务需求选择合适的工具,可以大大提高工作效率和系统管理的便利性。
107 25
|
1月前
|
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
77 24
Linux系统之whereis命令的基本使用
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
56 11
|
3月前
|
linux查看目录下的文件夹命令,find查找某个目录,但是不包括这个目录本身?
通过本文的介绍,您应该对如何在 Linux 系统中查看目录下的文件夹以及使用 `find` 命令查找特定目录内容并排除该目录本身有了清晰的理解。掌握这些命令和技巧,可以大大提高日常文件管理和查找操作的效率。 在实际应用中,灵活使用这些命令和参数,可以帮助您快速定位和管理文件和目录,满足各种复杂的文件系统操作需求。
209 8
Linux grep技巧 结合awk查询
结合 `grep` 和 `awk`,可以实现灵活、高效的文本处理和数据分析。`grep` 用于快速过滤符合条件的行,`awk` 用于进一步处理和提取数据。这种组合使用在日志分析、数据处理和系统监控等场景中尤为常见。掌握这两者的基本用法和组合技巧,可以大大提升在 Linux 环境下的工作效率。
72 7
|
3月前
|
Linux 各发行版安装 ping 命令指南
如何在不同 Linux 发行版(Ubuntu/Debian、CentOS/RHEL/Fedora、Arch Linux、openSUSE、Alpine Linux)上安装 `ping` 命令,详细列出各发行版的安装步骤和验证方法,帮助系统管理员和网络工程师快速排查网络问题。
312 20