小迅的神奇海螺

awk命令详解

2021-08-17

awk命令详解

0x01 功能说明

awk是处理文本文件的一个应用程序,几乎所有 Linux 系统都自带这个程序

它依次处理文件的每一行,并读取里面的每一个字段。对于日志、CSV 那样的每行格式相同的文本文件,awk可能是最方便的工具

awk其实不仅仅是工具软件,还是一种编程语言

0x02 实验环境

Debian:bullseye-slim

0x03 命令的安装

apt-get install gawk

几乎所有的系统都内置了这个命令,按需执行即可

0x04 命令文档

命令帮助

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
Usage: mawk [Options] [Program] [file ...]

Program:
The -f option value is the name of a file containing program text.
If no -f option is given, a "--" ends option processing; the following
parameters are the program text.

Options:
-f program-file Program text is read from file instead of from the
command-line. Multiple -f options are accepted.
-F value sets the field separator, FS, to value.
-v var=value assigns value to program variable var.
-- unambiguous end of options.

Implementation-specific options are prefixed with "-W". They can be
abbreviated:

-W version show version information and exit.
-W dump show assembler-like listing of program and exit.
-W help show this message and exit.
-W interactive set unbuffered output, line-buffered input.
-W exec file use file as program as well as last option.
-W random=number set initial random seed.
-W sprintf=number adjust size of sprintf buffer.
-W posix_space do not consider "\n" a space.
-W usage show this message and exit.

常用参数

awk命令的主要用法还是写程序实现功能,常用参数并不多

选项 说明
-F 指定分隔符
-f 指定程序文件

print和printf

awk中同时提供了print和printf两种打印输出的函数

其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂

常用变量

变量名 说明
$+数字N 表示第N个字段
NF 表示当前行字段总数
NR 表示当前正在处理的行数
FILENAME 当前文件名
FS 字段分隔符,默认是空格和制表符。
RS 行分隔符,用于分割每一行,默认是换行符。
OFS 输出字段的分隔符,用于打印时分隔字段,默认为空格。
ORS 输出记录的分隔符,用于打印时分隔记录,默认为换行符。
OFMT 数字输出的格式,默认为%.6g。

函数

函数名 说明
tolower() 字符转为小写
length() 返回字符串长度
substr() 返回子字符串
sin() 正弦
cos() 余弦
sqrt() 平方根
rand() 随机数

0x05 awk编程

代码块应写在{}内,多个代码块可以用{} END {}格式来写。每个语句之间用;分隔,只有一个语句时,可以不写;

变量和赋值

内置变量

输出/etc/passwd的账户名

1
2
3
4
5
6
$ awk -F: '{ print $1 }' /etc/passwd
root
daemon
bin
sys
sync

$1表示第一个字段,在前面加上print表示打印到控制台

自定义变量

统计/etc/passwd的账户人数

1
2
$ awk -F: '{ count++ } END { print "user count is ", count }' /etc/passwd
user count is 5

自定义变量不需要提前声明

条件

1
2
3
4
5
$ awk -F: '/usr/ {print $1}' /etc/passwd
root
daemon
bin
sys

print命令前面是一个正则表达式,只输出包含usr的行

数组

array_name[key] = value

awk支持K-V 键值对的数据结构,存储在内部的一张针对key/value应用hash的表格里

key可以是数字或字符串

和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串

一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。

举例:统计每个用户组下有多少名用户

1
$ awk -F: '{ ++S[$4] } END { for (a in S) print a,S[a] }' /etc/passwd

if语句

1
2
3
4
5
6
$ awk -F: '{if ($1 > "m") print $1; else print "---"}' demo.txt
root
---
---
sys
sync

上面代码输出第一个字段的第一个字符大于m的行,可以手动指定else输出“—”

循环语句

awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同

如果只是希望遍历文件的每一行,则完全不需要靠循环语句实现,例如自定义变量一节

若要遍历再循环,则将代码写在{}里面,然后用END分隔,例如数组一节

参考资料

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章