awk 简介
awk 是一个文本处理工具,通常用于处理数据并生成结果报告,awk的命名是它的创始人 Alfred Aho、 Peter Weinberger 和 Brian Kernighan 姓氏的首个字母组成的。
工作原理
- 通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。
- 完成 BEGIN 块的执行,开始执行 body 块。
- 读入有 \n 换行符分割的记录。
- 将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),$1 表示第一个域,$n 表示第 n 个域。
- 依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。
- 循环读取并执行各行直到文件结束,完成 body 块执行。
- 开始 END 块执行,END 块可以输出最终结果。
首先执行 BEGIN(只执行一次),再根据文本一行一行执行pattern{commands}(类似于sed),最好执行 END(只执行一次)
语法格式
格式类型 | 命令 |
格式一 | awk ‘BEGIN{}pattern{commands}END{}’ file_name |
格式二 | standard output | awk’BEGIN{}pattern{commands}END{}’ |
语法格式 | 解释 |
BEGIN{} | 正式处理数据之前执行 |
pattern | 匹配模式(和sed pattern 一样) |
{commands} | 处理命令,可能多行 |
END{} | 处理完所有匹配数据后执行 |
内置变量
语法格式 | 解释 |
$0 | 打印行所有信息 |
$1 - $n | 打印行的第 1 到 n 个字段的信息 |
NF (Number Field) | 处理行的字段个数 |
NR (Number Row) | 处理行的行号 |
FNR (File Number Row) | 多文件处理时,每个文件单独记录行号 |
FS (Field Separator) | 字段分割符,不指定时默认以空格或 tab 键分割 |
RS (Field Separator) | 行分隔符,不指定时以回车分割 \n |
OFS | 输出字段分隔符 |
ORS | 输出行分隔符 |
FILENAME | 处理文件的文件名 |
ARGC | 命令行参数个数 |
ARGV | 命令行参数数组 |
每行字段数索引开始为 1 并不为 0
例子
新建文件 student.txt
,string.txt
> cat student.txt allen 80 90 87 91 mike 78 86 93 96 Kobe 66 92 82 78 Jerry 98 74 66 54 wang 87 21 100 43 > cat string.txt Hadoop|Spark|Flume--Javal|Python|Scala|Go--Allen|Mike|Meggie
- 打印行所有信息
> awk '{print $0}' student.txt allen 80 90 87 91 mike 78 86 93 96 Kobe 66 92 82 78 Jerry 98 74 66 54 wang 87 21 100 43
- 打印行的第 1 到 2 个字段的信息
> awk '{print $1,$2}' student.txt allen 80 mike 78 Kobe 66 Jerry 98 wang 87
- 打印每行行的字段个数
> awk '{print NF}' student.txt 5 5 5 5 5
- 打印处理行的行号
> awk '{print NR}' student.txt 1 2 3 4 5
- 打印多文件单独记录行号
> awk '{print FNR}' string.txt student.txt 1 1 2 3 4 5
- 用
--
行分隔符和用|
列分割符分割行,且输出字段分隔符为&
> awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $3}' string.txt awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $3}' string.txt
- 输出文件名
> awk '{print FILENAME}' string.txt string.txt
格式化输出之 printf
格式符 | 含义 |
%s | 打印字符串 |
%d | 打印十进制数 |
%f | 打印一个浮点数 |
%x | 打印十六进制数 |
%o | 打印八进制数 |
%e | 打印数字的科学计数法形式 |
%c | 打印单个字符的 ASCII 码 |
修饰符
修饰符 | 含义 |
- | 左对齐 |
+ | 右对齐 |
# | 显示 8 进制在前面加 0,显示 16 进制在前面加 0x |
例子
- 以字符串格式打印 /etc/passwd 中的第 7 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%s \n",$7}' passwd /bin/bash /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/sync /sbin/shutdown /sbin/halt /sbin/nologin
- 以 10 进制格式打印 /etc/passwd 中的第 3 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%d \n",$3}' passwd 0 1 2 3 4 5 6 7 8 ...
- 以浮点数格式打印 /etc/passwd 中的第 3 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%f \n",$3}' passwd 0.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 ...
- 以 8 进制数格式打印 /etc/passwd 中的第 3 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%o \n",$3}' passwd 0 1 2 3 4 5 6 7 10 ...
- 以科学计数法格式打印 /etc/passwd 中的第 3 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%e \n",$3}' passwd 0.000000e+00 1.000000e+00 2.000000e+00 3.000000e+00 4.000000e+00 5.000000e+00 6.000000e+00 7.000000e+00 8.000000e+00 ...