awk 命令使用

1 简介

awk 是一种强大的文本处理工具和编程语言,主要用于处理格式化文本数据。它由 Alfred Aho、Peter Weinberger 和 Brian Kernighan 开发,名字的来源是三位作者名字的首字母。awk 是类 Unix 系统中标配的工具之一。

2 命令格式

awk [options] 'pattern {action}' inputFile
  • options: 命令参数
  • pattern: 指定条件,决定应用哪些行。可以是正则表达式、条件表达式等。
  • action:指定在匹配的行上执行的操作,通常是打印、修改、聚合等。
  • input_file:要处理的文件或输入。

3 参数

awk 命令主要有以下参数:

参数参数说明
-F指定输入字段分隔符(FSField Separator),默认是空格或制表符。
-vawk 程序开始执行之前定义一个变量及其初始值。

3.1 -F 参数

  • 作用:-F 参数在 awk 中用于指定输入的字段分隔符(FSField Separator)。通过它可以灵活地处理不同格式的文本文件,例如以逗号、冒号或其他符号分隔的文件。

  • 例子1:指定分隔符为 ",",并提取 data.csv 的第1和第3行

[root@doc-nginx opt] # 生成 data.csv 文件
[root@doc-nginx opt] cat >data.csv<<EOF
> name,age,city
> Alice,30,New York
> Bob,25,Los Angeles
> Charlie,35,Chicago
> EOF
[root@doc-nginx opt] # 指定分隔符为 “,”, 并输出第1列及第3列
[root@doc-nginx opt] awk -F ',' '{print $1, $3}' data.csv
name city
Alice New York
Bob Los Angeles
Charlie Chicago
  • 例子2:指定分隔符为 ","||,并输出第1列及第3列
[root@doc-nginx opt] cat data.csv
name,age||city
Alice,30||New York
Bob,25||Los Angeles
Charlie,35||Chicago
[root@doc-nginx opt]
[root@doc-nginx opt] awk -F ',|\\|\\|' '{print $1, $3}' data.csv 
name city
Alice New York
Bob Los Angeles
Charlie Chicago

解释:

(1) data.csv 的 第1列 跟 第2列 用 "," 分隔,第2列 跟 第3列 用 || 分隔。

(2) 使用正则表达式 ,|\|\| 指定分隔符,意思是,分隔符是逗号或 ||

3.2 -v 参数

  • 作用:-v 参数用于从命令行向 awk 脚本传递变量值。这样可以在运行脚本时动态设置变量,而无需修改脚本本身

  • 例子:读取 data.csv,传入变量 prefix,并把 prefix 变量与姓名一起打印出来

[root@doc-nginx opt] cat data.csv 
name,age||city
Alice,30||New York
Bob,25||Los Angeles
Charlie,35||Chicago
[root@doc-nginx opt] 
[root@doc-nginx opt] awk -F ',' -v prefix="Hello, " '{print prefix,$1}' data.csv
Hello,  name
Hello,  Alice
Hello,  Bob
Hello,  Charlie
[root@doc-nginx opt] awk -F ',' -v prefix="你好, " '{print prefix,$1}' data.csv
你好,  name
你好,  Alice
你好,  Bob
你好,  Charlie

4 变量

AWK 提供了一组预定义的内置变量,这些变量在脚本中非常有用,可以帮助我们轻松访问和操作输入数据、控制程序流程以及处理输出。

4.1 输入相关变量

变量描述
FSField Separator,输入字段分隔符,默认是空格或制表符。
RSRecord Separator,输入记录分隔符,默认是换行符。
FILENAME当前输入文件的名称。
NFNumber of Fields,当前记录的字段数。
NRNumber of Records,已处理的记录数(从第一个文件开始到当前记录)。
$0当前记录的内容(整行)。
$1, $2, ..., $n当前记录的各个字段内容。

4.1.1 FS 变量

  • 作用:输入字段分隔符,默认是空格或制表符
  • 例子:读取 data.csv,并指定分隔符为 ",",在输出结果打印分隔符
[root@doc-nginx opt] awk -F ',' '{print "分隔符是",FS}' data.csv 
分隔符是 ,
分隔符是 ,
分隔符是 ,
分隔符是 ,

4.1.2 RS 变量

  • 作用:输入记录分隔符,默认是换行符
  • 例子:指定记录分隔符变量 RS"#",然后把当前记录内容
[root@doc-nginx opt] cat >record.txt<<EOF
> hadoop#yarn#hive#spark#flink
> EOF
[root@doc-nginx opt] awk 'BEGIN {RS="#"} {print $0}' record.txt 
hadoop
yarn
hive
spark
flink

4.1.3 NF

  • 作用:当前记录的字段数
  • 例子:输出记录内容 及 当前行的字段数
[root@doc-nginx opt] cat >record.txt<<EOF
> field_1 field_2
> field_1 field_2 field_3
> field_1 field_2 field_3 field_4
> EOF
[root@doc-nginx opt] 
[root@doc-nginx opt] awk '{print $0,",有",NF,"字段"}' record.txt 
field_1 field_2 ,有 2 字段
field_1 field_2 field_3 ,有 3 字段
field_1 field_2 field_3 field_4 ,有 4 字段

4.1.4 NR

  • 作用:已处理的记录数
  • 例子:输出 行号 及 记录内容
[root@doc-nginx opt] awk '{print NR,$0}' record.txt 
1 field_1 field_2
2 field_1 field_2 field_3
3 field_1 field_2 field_3 field_4

4.2 输出相关变量

变量描述
OFSOutput Field Separator,输出字段分隔符,默认是空格。
ORSOutput Record Separator,输出记录分隔符,默认是换行符。
OFMTOutput Format,控制数值类型输出格式,默认是 %.6g(浮点数格式)。
CONVFMTConversion Format,数值转换为字符串的格式,默认是 %.6g。

4.2.1 OFS 变量

  • 作用:用于指定输出时字段之间的分隔符。默认情况下,OFS 的值是一个空格字符 " "。可以通过修改 OFS 来改变字段之间的分隔符,例如使用逗号制表符竖线等。
  • 例子:读取文件,输出每一列内容,并用竖线 "|" 分隔
[root@doc-nginx opt] cat >fruit.txt<<EOF
> apple banana cherry
> grape orange mango
> EOF
[root@doc-nginx opt] awk 'BEGIN {OFS="|"} {print $1,$2,$3}' fruit.txt 
apple|banana|cherry
grape|orange|mango

4.2.2 ORS 变量

  • 作用:用于指定输出时记录之间的分隔符。默认情况下,ORS 的值是换行符 \n。通过修改 ORS,可以改变输出记录之间的分隔符,例如使用空格、逗号或其他字符。
  • 例子:将输出记录之间的分隔符设置为逗号。每条记录之间输出一个逗号而不是换行符
[root@doc-nginx opt] cat fruit.txt 
apple banana cherry
grape orange mango
[root@doc-nginx opt] awk 'BEGIN {ORS="|"} {print $1,$2,$3}' fruit.txt 
apple banana cherry|grape orange mango

4.2.3 OFMT 变量

  • 作用:用于指定数字的输出格式。默认情况下,OFMT 的值是 %.6g,表示输出最多6位有效数字(根据需要使用科学记数法或定点数)。通过修改 OFMT,可以改变数字输出的精度和格式,例如控制输出的小数位数、是否使用科学记数法等。
  • 例子1:输出的结果固定2位小数
[root@doc-nginx opt] cat numbers.txt 
123.456789
9876.54321
[root@doc-nginx opt]
[root@doc-nginx opt] awk 'BEGIN {OFMT="%.2f"} {print $1+0}' numbers.txt 
123.46
9876.54
  • 例子2:以科学记数法输出数字,保留3位小数
[root@doc-nginx opt] cat numbers.txt 
123.456789
9876.54321
[root@doc-nginx opt]
[root@doc-nginx opt] awk 'BEGIN {OFMT="%.3e"} {print $1+0}' numbers.txt 
1.235e+02
9.877e+03

5 pattern(模式)

AWK 中,pattern(模式) 决定了哪些行会被处理。常见的 pattern 类型包括正则表达式、比较条件、范围模式、特殊模式(如 BEGINEND)、以及组合逻辑模式。

5.1 正则表达式模式

  • 作用:匹配行中的文本。
  • 语法:/正则表达式/
  • 例子1:/apple/ 匹配所有包含 "banana" 的行。
[root@doc-nginx opt] cat >fruit.txt<<EOF
> apple banana cherry
> orange banana mango
> grape orange banana
> EOF
[root@doc-nginx opt] awk '/apple/' fruit.txt 
apple banana cherry
  • 例子2:匹配以特定单词开头的行
[root@doc-nginx opt] cat fruit.txt 
apple banana cherry
orange banana mango
grape orange banana
[root@doc-nginx opt]
[root@doc-nginx opt] awk '/^orange/' fruit.txt 
orange banana mango

5.2 关系运算模式

  • 作用:基于 字段变量值 的比较条件。
  • 语法:表达式
  • 例子1:匹配第一列的值大于10的行
[root@doc-nginx opt] cat >fruit.txt<<EOF
> 5  banana
> 15 orange
> 10 grape
> 20 cherry
> EOF
[root@doc-nginx opt] awk '$1 > 10' fruit.txt 
15 orange
20 cherry
  • 例子2:匹配第三列等于特定值的行
[root@doc-nginx opt] cat >data.txt<<EOF
> Alice 30 Female
> Bob 25 Male
> Charlie 35 Male
> EOF
[root@doc-nginx opt] awk '$3 == "Male"' data.txt 
Bob 25 Male
Charlie 35 Male
  • 例子3:匹配第三列等于 Male 且 第二列等于 35 的行
[root@doc-nginx opt] cat data.txt 
Alice 30 Female
Bob 25 Male
Charlie 35 Male
[root@doc-nginx opt] awk '$3 == "Male" && $2 == 35' data.txt 
Charlie 35 Male

5.3 范围模式

  • 作用:匹配 起始结束 模式之间的 所有行
  • 语法:pattern1, pattern2
  • 例子 1:匹配从第一列值为 5 到第一列值为 10 的行
[root@doc-nginx opt] awk '$1 == 5,$1 == 10' fruit.txt 
5  banana
15 orange
10 grape
  • 例子2:匹配从单词 step 到单词 end 的行
[root@doc-nginx opt] cat >log.txt<<EOF
> start processing
> step 1 complete
> step 2 complete
> end processing
> EOF
[root@doc-nginx opt] awk '/step/,/end/' log.txt 
step 1 complete
step 2 complete
end processing

5.4 BEGIN 和 END 模式

  • 作用:BEGIN处理输入行之前 运行 1 次,END处理完所有行之后 运行 1 次。
  • 语法:BEGIN {actions}END {actions}
  • 例子1:BEGIN 块在任何输入行处理之前运行,打印 "Header:"
[root@doc-nginx opt] awk 'BEGIN {print "Users: "} {print $0}' data.txt 
Users: 
Alice 30 Female
Bob 25 Male
Charlie 35 Male
  • 例子2:END 块在所有行处理完之后运行,打印总行数 NR
[root@doc-nginx opt] awk '{print $0} END {print "Total users:",NR}' data.txt 
Alice 30 Female
Bob 25 Male
Charlie 35 Male
Total users: 3

5.5 组合模式

  • 作用:通过逻辑运算符将多个模式组合起来。
  • 语法:

(1) pattern1 && pattern2:同时满足两个条件。

(2) pattern1 || pattern2:满足任意一个条件。

(3) !pattern:取反,匹配不满足条件的行。

  • 例子1:匹配包含 "banana" 且第一列值大于 10 的行
[root@doc-nginx opt] cat fruit.txt 
5  banana
15 orange
10 grape
20 cherry
10 banana
[root@doc-nginx opt] awk '/banana/ && $1 >= 10' fruit.txt 
10 banana
  • 例子2:匹配包含 “banana” 或 “grape” 的行
[root@doc-nginx opt] cat fruit.txt 
5  banana
15 orange
10 grape
20 cherry
10 banana
[root@doc-nginx opt] awk '/banana/ || /grape/' fruit.txt 
5  banana
10 grape
10 banana
  • 例子3:匹配不包含 “banana” 的行
[root@doc-nginx opt] cat fruit.txt 
5  banana
15 orange
10 grape
20 cherry
10 banana
[root@doc-nginx opt] awk '!/banana/' fruit.txt 
15 orange
10 grape
20 cherry

6 action

模式 匹配成功时,执行与之对应的 action(操作)。如果没有指定 pattern,则会对每一行都执行对应的 actionaction 可以包含任意的 awk 语句,包括 输出变量控制结构(如循环、条件判断)等。

6.1 使用控制结构(循环、条件语句)

6.1.1 使用 for 循环

awk 中的 for 循环语法与其他编程语言相似。常见的用法包括循环遍历数组或重复执行某个操作。

  • 例子:遍历每一个字段并逐个输出
[root@doc-nginx opt] cat fruit.txt 
5  banana
15 orange
10 grape
20 cherry
10 banana
[root@doc-nginx opt] awk '{for(i=1; i<=NF; i++) print $i}' fruit.txt 
5
banana
15
orange
10
grape
20
cherry
10
banana

6.1.2 使用 while 循环

awk 也支持 while 循环,它在某些情况下可能更方便,尤其是需要基于条件执行某些操作时。

  • 例子:遍历每一个字段并逐个输出
[root@doc-nginx opt] cat fruit.txt 
5  banana
15 orange
10 grape
20 cherry
10 banana
[root@doc-nginx opt] awk '{i = 1; while(i <= NF) { print $i; i++; }}' fruit.txt 
5
banana
15
orange
10
grape
20
cherry
10
banana

6.2 数组的使用

awk 允许使用数组来存储数据。数组的索引可以是任何字符串或数字,数组本身是动态的,不需要预先定义大小。

6.2.1 数组的基本使用

  • 例子:将每一行的第一列作为数组的 键(索引),第二列作为数组的 。在 END 块中,使用 for (key in arr) 遍历数组,输出每个
[root@doc-nginx opt] cat fruit.txt 
5  banana
15 orange
10 grape
20 cherry
10 banana
[root@doc-nginx opt] awk '{arr[$2] = $1} END { for (key in arr) {print key, ":", arr[key]} }' fruit.txt 
orange : 15
banana : 10
grape : 10
cherry : 20

6.2.2 数组统计

  • 例子:使用数组统计每个单词的出现次数
[root@doc-nginx opt] cat >fruit2.txt<<EOF
> apple
> banana
> apple
> orange
> banana
> banana
> grape
> EOF
[root@doc-nginx opt] awk '{count[$1]++} END {for(key in count) print key, ":" , count[key]}' fruit2.txt 
orange : 1
apple : 2
banana : 3
grape : 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值