目录
7.BEGIN 和 END 块在处理任何输入行之前和之后执行的代码
6.提取每一行第一个字段的子字符串(从第二个字符开始,长度为 3)
AWK 是一个强大的文本处理工具,可以根据指定的模式和动作来处理数据。在 shell 中,AWK 的参数和内置命令非常丰富,以下是一个总结表格,涵盖了一些常用的参数和命令。
| 参数/内置命令 | 描述 | 示例 |
|-------------|--------------------------------|---------------------------------------------------|
| -F fs | 指定输入字段分隔符 | awk -F, '{print $1}' file |
| -v var=val | 为 AWK 程序传递变量 | awk -v num=5 '{print $1, num}' file |
| -f script | 从脚本文件中读取 AWK 程序 | awk -f script.awk file |
| BEGIN | 在处理任何输入行之前执行 | awk 'BEGIN {print "Start"} {print $1}' file |
| END | 在处理完所有输入行之后执行 | awk '{print $1} END {print "End"}' file |
| $0 | 当前记录的内容 | awk '{print $0}' file |
| $1, $2, ... | 当前记录的第 n 个字段 | awk '{print $1, $2}' file |
| NR | 已读取的记录数,即行号 | awk '{print NR, $0}' file |
| NF | 当前记录中的字段数 | awk '{print $1, NF}' file |
| FS | 输入字段分隔符 | awk 'BEGIN {FS=","} {print $1}' file |
| OFS | 输出字段分隔符 | awk 'BEGIN {OFS=","} {print $1, $2}' file |
| RS | 输入记录分隔符 | awk 'BEGIN {RS="\n"} {print $1}' file |
| ORS | 输出记录分隔符 | awk 'BEGIN {ORS=";"} {print $1}' file |
| getline | 从输入中获取下一行数据 | awk '{getline; print $0}' file |
| length | 字符串长度 | awk '{print length($1)}' file |
| substr(s, m, n)| 子字符串提取 | awk '{print substr($1, 2, 3)}' file |
| match | 返回正则表达式匹配的位置 | awk 'match($1, /regex/) {print RSTART, RLENGTH}' file |
| gsub | 全局替换字符串 | awk '{gsub(/old/, "new", $1); print}' file |
| split | 将字符串拆分成数组 | awk '{split($1, arr, ","); print arr[1]}' file |
| sprintf | 格式化输出 | awk '{print sprintf("%s - %d", $1, $2)}' file |
| system | 执行系统命令 | awk 'BEGIN {system("date")}' |
| FILENAME | 当前输入文件的文件名 | awk '{print FILENAME, $0}' file |
| ARGC | 命令行参数的数量 | awk 'BEGIN {print ARGC}' |
| ARGV | 命令行参数数组 | awk 'BEGIN {for (i=1; i<ARGC; i++) print ARGV[i]}' |
| ENVIRON | 环境变量数组 | awk 'BEGIN {print ENVIRON["HOME"]}' |
常用内置变量扩展介绍
- $0:当前行的文本内容。
- $n:当前行的第n个字段,例如$1表示第一个字段。
- NR:当前行号。
- NF:当前行的字段数。
- FNR: 不同文件各自显示行号
- FS:字段分隔符,默认为空格或制表符。
- OFS:输出字段分隔符,默认为空格。
- RS:输入记录分隔符,默认为换行符。
- ORS:输出记录分隔符,默认为换行符。
基本语法
awk 'pattern {action}' file
- pattern:模式部分,可以是一个正则表达式,用于匹配输入记录。
- action:动作部分,用于指定对匹配到的记录进行的操作。
- file:输入文件,可以是一个或多个文件。
使用案例
基本用法
1.打印文件中的所有行
awk '{print}' filename
打印出filename文件里的所有行
2.打印特定字段
awk '{print $1, $3}' filename
这会打印文件中的第一列和第三列,列之间以空格分隔。
3.打印每一行的行号和内容
awk '{print NR, $0}' filename
4.打印每一行的字段数和内容
awk '{print NF, $0}' filename
字段操作
1.使用逗号作为字段分隔符
awk -F ',' '{print $1, $2}' filename.csv
2.使用特定分隔符进行输出
awk 'BEGIN {OFS = "|"}; {print $1, $2}' filename
3.传递 shell 变量到 AWK
count=5
awk -v var=$count '{print $1, var}' filename
条件处理
1.匹配特定模式
awk '/pattern/ {print}' filename
这会打印所有包含指定模式的行。
2.打印所有包含 "error" 的行
awk '/error/ {print}' filename
3.打印第二个字段大于 50 的行
awk '$2 > 50 {print}' filename
4.打印第一个字段等于 "Alice" 的行
awk '$1 == "Alice" {print}' filename
5.设置字段分隔符
awk 'BEGIN {FS=","} {print $1, $2}' filename
这会将字段分隔符设置为逗号,并打印第一列和第二列。
6.条件判断
awk '$3 > 50 {print $1, $3}' filename
这会打印第三列大于50的行的第一列和第三列。
7.BEGIN 和 END 块在处理任何输入行之前和之后执行的代码
awk 'BEGIN {print "Start of file"}; {print}; END {print "End of file"}' filename
使用函数
1.内置函数
awk '{print toupper($0)}' filename
这会将每行的文本内容转换为大写。
2.计算字段和
awk '{sum += $1} END {print sum}' filename
这会计算第一列的和,并在处理完所有行后打印结果。
3计算某一列的平均值
awk '{sum += $2; count++} END {print sum / count}'
4.格式化输出
awk '{printf "Name: %s, Score: %d\n", $1, $2}' filename
这会将输出格式化为“Name: [第一列], Score: [第二列]”。
5.计算每一行第一个字段的长度
awk '{print $1, length($1)}' filename
6.提取每一行第一个字段的子字符串(从第二个字符开始,长度为 3)
awk '{print substr($1, 2, 3)}' filename
使用awk脚本文件
假设有一个 script.awk
文件,包含以下内容:
BEGIN {
FS = ","
OFS = "|"
print "Name", "Age"
}
{
print $1, $2
}
END {
print "End of file"
}
使用 awk
调用这个脚本文件
awk -f script.awk filename
实际应用
1.统计日志文件中每个 IP 地址的访问次数
awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log
2.替换文件中的所有 "foo" 为 "bar" 并输出
awk '{gsub(/foo/, "bar"); print}' filename
3.将文件字段拆分成数组并访问其中的元素
awk '{split($1, arr, "-"); print arr[1], arr[2]}' filename
4.过滤出用户的环境变量
awk 'BEGIN {for (i in ENVIRON) print i, ENVIRON[i]}' filename
扩展:
awk
是一种强大的文本处理工具,允许用户使用模式匹配和操作数据。awk
中的 print
、printf
和 sprintf
是用于输出文本的命令,各自有不同的用途和特性。
1. print
print
是 awk
中最常用的输出语句,用于打印简单的文本、字段或表达式。它会在每个字段之间自动添加空格,并在每行末尾添加一个换行符。
示例:
# 简单的文本输出
echo "Hello World" | awk '{print "Hello, AWK!"}'
# 输出特定字段
echo "John Doe 30" | awk '{print $1, $3}'
# 输出计算结果
echo "5 10" | awk '{print $1 + $2}'
2. printf
printf
类似于 C 语言中的 printf
,允许格式化输出。你可以精确控制输出的格式,例如指定字段的宽度、对齐方式和小数位数。printf
提供了比 print
更灵活的输出选项,但需要手动添加换行符。
示例:
# 简单的格式化输出
echo "Hello World" | awk '{ printf "Hello, %s!\n", "AWK" }'
# 格式化输出特定字段
echo "John Doe 30" | awk '{ printf "%-10s %-10s %d\n", $1, $2, $3 }'
# 格式化输出计算结果
echo "5 10" | awk '{ printf "Result: %.2f\n", $1 + $2 }'
3. sprintf
sprintf
和 printf
类似,但不是直接输出,而是生成一个格式化的字符串,可以在后续的运算中使用。例如,你可以使用 sprintf
将格式化的字符串赋值给一个变量,并在 print
或其他操作中使用。
示例:
# 格式化字符串赋值
echo "Hello World" | awk '{ msg = sprintf("Hello, %s!", "AWK"); print msg }'
# 格式化字符串组合
echo "John Doe 30" | awk '{ fullname = sprintf("%s %s", $1, $2); print fullname }'
# 结合使用打印计算结果
echo "5 10" | awk '{ result = sprintf("Result: %.2f", $1 + $2); print result }'
总结
print
:用于简单输出,自动添加空格和换行符。printf
:用于格式化输出,提供更高的灵活性,需要手动添加换行符。sprintf
:用于生成格式化字符串,不是直接输出,而是将字符串存储在变量中,供后续操作使用。