Shell 编程(六):文本三剑客之 awk(一)

简介: awk 是一个文本处理工具,通常用于处理数据并生成结果报告,awk的命名是它的创始人 Alfred Aho、 Peter Weinberger 和 Brian Kernighan 姓氏的首个字母组成的。

awk 简介

awk 是一个文本处理工具,通常用于处理数据并生成结果报告,awk的命名是它的创始人 Alfred Aho、 Peter Weinberger 和 Brian Kernighan 姓氏的首个字母组成的。

工作原理

  1. 通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。
  2. 完成 BEGIN 块的执行,开始执行 body 块。
  3. 读入有 \n 换行符分割的记录。
  4. 将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),$1 表示第一个域,$n 表示第 n 个域。
  5. 依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。
  6. 循环读取并执行各行直到文件结束,完成 body 块执行。
  7. 开始 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


  1. 打印行所有信息
> 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. 打印行的第 1 到 2 个字段的信息
> awk '{print $1,$2}' student.txt
allen 80
mike 78
Kobe 66
Jerry 98
wang 87


  1. 打印每行行的字段个数
> awk '{print NF}' student.txt
5
5
5
5
5


  1. 打印处理行的行号
> awk '{print NR}' student.txt
1
2
3
4
5


  1. 打印多文件单独记录行号
> awk '{print FNR}' string.txt student.txt
1
1
2
3
4
5


  1. -- 行分隔符和用 | 列分割符分割行,且输出字段分隔符为 &
> awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $3}' string.txt
awk 'BEGIN{RS="--";FS="|";ORS="&"}{print $3}' string.txt


  1. 输出文件名
> awk '{print FILENAME}' string.txt
string.txt


格式化输出之 printf

格式符 含义
%s 打印字符串
%d 打印十进制数
%f 打印一个浮点数
%x 打印十六进制数
%o 打印八进制数
%e 打印数字的科学计数法形式
%c 打印单个字符的 ASCII 码

修饰符

修饰符 含义
- 左对齐
+ 右对齐
# 显示 8 进制在前面加 0,显示 16 进制在前面加 0x

例子

  1. 以字符串格式打印 /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


  1. 以 10 进制格式打印 /etc/passwd 中的第 3 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%d \n",$3}' passwd
0 
1 
2 
3 
4 
5 
6 
7 
8 
...


  1. 以浮点数格式打印 /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
...


  1. 以 8 进制数格式打印 /etc/passwd 中的第 3 个字段,以 “:” 作为分隔符
> awk 'BEGIN{FS=":"}{printf "%o \n",$3}' passwd
0 
1 
2 
3 
4 
5 
6 
7 
10
...


  1. 以科学计数法格式打印 /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
...


目录
相关文章
|
1月前
|
Shell Linux Perl
Linux|如何允许 awk 使用 Shell 变量
Linux|如何允许 awk 使用 Shell 变量
37 2
|
1天前
|
机器学习/深度学习 Unix Java
技术笔记:Linux之Shell脚本编程(一)
技术笔记:Linux之Shell脚本编程(一)
|
10天前
|
Shell Perl
7操作系统基础-Shell编程
7操作系统基础-Shell编程
7 0
|
1月前
|
监控 关系型数据库 Shell
Shell脚本入门:从基础到实践,轻松掌握Shell编程
Shell脚本入门:从基础到实践,轻松掌握Shell编程
|
1月前
|
存储 Shell C语言
shell脚本 编程 变量 基本入门(详解)
shell脚本 编程 变量 基本入门(详解)
|
1月前
|
监控 Shell 开发工具
Shell编程
Shell编程
|
1月前
|
存储 网络协议 Shell
第十章 Shell编程时常用的系统文件
第十章 Shell编程时常用的系统文件
|
1月前
|
存储 Shell 索引
第七章 Shell文本处理三剑客之awk
第七章 Shell文本处理三剑客之awk
|
8月前
|
网络协议 Shell Linux
【Linux】shell编程基础(超详细,入门看这一篇就够了)(下)
【Linux】shell编程基础(超详细,入门看这一篇就够了)(下)
81 0
|
8月前
|
Java Shell Linux
【Linux】shell编程基础(超详细,入门看这一篇就够了)(上)
【Linux】shell编程基础(超详细,入门看这一篇就够了)
540 0