shell-awk语法整理
- 前言
- 基本语法
- 内置变量
- 1. $0
- 2. NF
- 3. NR
- 4. FS
- 5. RS
- 6. OFS
- 7. ORS
- 8. FILENAME
- 9. FNR
- 10. ARGV
- 11. ENVIRON
- 12. IGNORECASE
- 13. RSTART 和 RLENGTH
- 示例解释
- 内置函数
- 循环语句(后面的';'可不加)
- 条件语句
- 高级特性
- 示例
- 特殊模式
- BEGIN
- END
- 组合示例
- BEGINFILE 和 ENDFILE
- getline 模式
- 总结
- 常用命令行选项
前言
AWK是一种功能强大的文本处理工具,可根据指定的规则对文本和数据文件进行逐行处理,通过灵活使用模式和动作的组合,可以实现复杂的文本分析和数据处理任务,适合处理各种格式的文本文件和数据流
基本语法
AWK的基本语法结构为:
awk pattern '{ action }' filename
- pattern:用来匹配输入数据的模式
- action:在匹配到符合模式的行时执行的操作
- filename:要操作的目标文件
例如,要打印每行以字母 “a” 开头的文本:
awk '/^a/ { print }' filename
其中,/^a/ 是模式,{ print } 是操作,会打印文件中所有以字母 “a” 开头的行
内置变量
AWK 提供了许多内置变量,用于获取关于输入数据、当前行、行号等信息
1. $0
- 描述:代表当前行的内容
- 示例:打印所有行的内容(print后面什么都不带,也是一样的效果)
awk '{ print $0 }' filename
2. NF
- 描述:代表当前行的字段数
- 示例:打印每行的字段数
awk '{ print NF }' filename
3. NR
- 描述:代表当前行的行号
- 示例:打印每行的行号和内容
awk '{ print NR, $0 }' filename
4. FS
- 描述:代表字段分隔符,默认是空白字符
- 示例:使用不同的字段分隔符打印字段内容
awk -F':' '{ print $1, $2 }' filename
5. RS
- 描述:代表记录分隔符,默认是换行符
- 示例:按不同的记录分隔符处理数据
awk 'BEGIN { RS="@" } { print $0 }' filename
6. OFS
- 描述:代表输出字段分隔符
- 示例:设置不同的输出字段分隔符
awk 'BEGIN { OFS=" | " } { print $1, $2 }' filename
7. ORS
- 描述:代表输出记录分隔符
- 示例:设置不同的输出记录分隔符
awk 'BEGIN { ORS="\n\n" } { print $0 }' filename
8. FILENAME
- 描述:代表当前输入文件的名称
- 示例:打印当前处理的文件名
awk '{ print FILENAME }' filename
9. FNR
- 描述:代表当前处理的文件中的行号,从1开始计数
- 示例:打印当前处理的行号和内容
awk '{ print FNR, $0 }' filename
10. ARGV
- 描述:一个包含命令行参数的数组
- 示例:遍历打印命令行参数
awk 'BEGIN { for (i = 0; i < ARGC; i++) print ARGV[i] }' file1 file2
11. ENVIRON
- 描述:一个包含环境变量的关联数组
- 示例:打印所有环境变量及其值
awk 'BEGIN { for (var in ENVIRON) print var, ENVIRON[var] }'
12. IGNORECASE
- 描述:控制字符串匹配时是否忽略大小写
- 示例:在匹配时忽略大小写
awk 'BEGIN { IGNORECASE=1 } /pattern/ { print }' filename
13. RSTART 和 RLENGTH
- 描述:
- RSTART:上次 match() 函数匹配的起始位置
- RLENGTH:上次 match() 函数匹配的长度
- 示例:使用 match() 函数找到并打印匹配的子字符串及其位置
awk '{ if (match($0, /pattern/)) print "Found:", substr($0, RSTART, RLENGTH) }' filename
示例解释
- $0:表示当前行的全部内容
- NF:表示当前行的字段数
- NR:表示当前行的行号
- FS:用于指定字段分隔符
- RS:用于指定记录分隔符
- OFS:用于指定输出字段分隔符
- ORS:用于指定输出记录分隔符
- FILENAME:用于输入文件的名称
- FNR:用于输入当前处理的文件中的行号
- ARGV:输出命令行参数的数组
- ENVIRON:输出环境变量的关联数组
- IGNORECASE:控制字符串匹配时是否忽略大小写
- RSTART:上次 match() 函数匹配的起始位置
- RLENGTH:上次 match() 函数匹配的长度
内置函数
AWK 提供了多种内置函数,用于字符串处理、数学计算等
- 字符串函数:
- length(str):返回字符串长度
- index(str, search):返回搜索字符串在原字符串中的位置
- split(str, arr, sep):将字符串按分隔符分割成数组
- 数学函数:
- sin(x)、cos(x)、sqrt(x):三角函数和平方根函数
- rand():返回一个0到1之间的随机数
循环语句(后面的’;'可不加)
AWK支持类C语言风格的循环语句:
- for循环:
for (i = 1; i <= 10; i++) {
print i;
}
- while循环:
while (condition) {
print $0;
getline;
}
条件语句
AWK 中的条件语句与其他编程语言类似:
- if语句:
if (condition) {
print "Condition is true";
} else {
print "Condition is false";
}
- switch语句:
switch (variable) {
case value1: {
print "Value 1";
break;
}
case value2: {
print "Value 2";
break;
}
default: {
print "Default case";
break;
}
}
高级特性
AWK还支持更高级的特性,如函数定义、数组操作和模式动作的组合使用:
- 函数定义:
function add(x, y) {
return x + y;
}
- 数组操作:
# 创建数组
arr["key1"] = "value1";
arr["key2"] = "value2";
# 遍历数组
for (key in arr) {
print key, arr[key];
}
示例
演示了AWK的基本语法、内置变量、函数、循环和条件语句的使用:
# AWK script to print lines containing "error"
# and count lines where first field is numeric
# Print lines containing "error"
/error/ {
print;
}
# Count lines where first field is numeric
$1 ~ /^[0-9]+$/ {
count++;
}
# END block to print count
END {
print "Numeric lines count:", count;
}
特殊模式
BEGIN
-
描述:BEGIN 块用于在处理任何输入数据之前执行初始化任务,例如设置变量、打印标题、配置输出格式等BEGIN 块中的代码在任何输入数据处理之前运行一次
-
示例:打印表头,并设置字段分隔符
awk 'BEGIN { OFS = "\t"; print "Name", "Age", "City" } { print $1, $2, $3 }' filename
示例中在处理 filename 文件之前,会打印表头 “Name”, “Age”, “City”,并将输出字段分隔符 (OFS) 设置为制表符
END
-
描述:END 块用于在处理所有输入数据之后执行任务,例如打印总结信息、计算总和或平均值等。END 块中的代码在所有输入数据处理完后运行一次
-
示例:计算并打印行数
awk 'END { print "Total lines:", NR }' filename
示例中在处理完 filename 文件的所有行之后,打印总行数,其中 NR 是记录数的内置变量,表示总行数
组合示例
可同时使用 BEGIN 和 END 块来初始化和总结数据处理:
awk 'BEGIN { print "Processing file:", FILENAME }
{ sum += $2 }
END { print "Total sum of second column:", sum }' filename
- BEGIN { print “Processing file:”, FILENAME }:在处理任何数据之前打印当前处理的文件名
- { sum += $2 }:处理每一行,将第二列的值累加到 sum 变量中
- END { print “Total sum of second column:”, sum }:在处理完所有数据后,打印第二列值的总和
BEGINFILE 和 ENDFILE
-
描述:
- BEGINFILE:在处理每个输入文件之前执行一次
- ENDFILE:在处理每个输入文件之后执行一次
-
示例:
awk 'BEGINFILE { print "Start processing", FILENAME }
{ print $0 }
ENDFILE { print "End processing", FILENAME }' file1 file2
示例会在处理每个输入文件 file1 和 file2 前后分别打印处理开始和处理结束的消息
getline 模式
-
描述:
- getline 模式用于手动从输入中读取下一行并处理。可与条件和循环结构一起使用,以控制输入数据的处理方式
-
示例:
awk '/pattern/ {
print "Found:", $0
if (getline next_line > 0) {
print "Next line:", next_line
}
}' filename
示例会在匹配到某个模式后,打印当前行和下一行的内容(如果存在)
总结
- BEGIN:特殊模式块,用于在处理输入数据之前执行初始化操作
- END:特殊模式块,用于在处理完所有输入数据后执行总结或清理操作
- BEGINFILE 和 ENDFILE:用于在处理每个输入文件前后执行特定操作
- getline模式:允许在脚本执行过程中手动控制输入行的读取和处理方式
常用命令行选项
- -F separator
- 描述:指定字段分隔符。默认情况下,字段分隔符为任何空白字符序列
- 示例:
awk -F ',' '{ print $1 }' filename
-F ',' 指定逗号为字段分隔符,然后打印每行的第一个字段
- -v var=value
- 描述:设置 AWK 变量的值。可以在 AWK 脚本中使用 -v 选项来传递变量
- 示例:
awk -v threshold=50 '$1 > threshold { print $0 }' filename
示例中,定义了一个变量 threshold 并将其传递给 AWK 脚本,然后根据条件打印符合要求的行
- -f script-file
- 描述:从指定的文件中读取 AWK 脚本
- 示例:
awk -f myscript.awk data.txt
示例中,AWK 将执行 myscript.awk 文件中的脚本来处理 data.txt 文件