3.3.1 记录和字段
# 打印所有记录
echo "=== 打印所有记录 ==="
awk '{print}' data.txt
详细解释:
-
awk
:文本分析工具 -
{print}
:动作块,打印当前记录 -
默认打印整行内容
-
等同于
{print $0}
# 打印第一字段
echo -e "\n=== 打印第一字段 ==="
awk '{print $1}' data.txt
详细解释:
-
$1
:第一个字段 -
默认以空白字符(空格、制表符)分隔
-
输出每行的第一个字段
# 打印第一和第三字段
echo -e "\n=== 打印第一和第三字段 ==="
awk '{print $1, $3}' data.txt
详细解释:
-
$1, $3
:打印第一和第三字段 -
字段间自动用OFS(输出字段分隔符,默认空格)分隔
-
多字段输出
# 打印所有字段
echo -e "\n=== 打印所有字段 ==="
awk '{print $0}' data.txt
详细解释:
-
$0
:整个记录(整行) -
与
{print}
效果相同 -
显式引用整行
# 打印字段数量
echo -e "\n=== 打印字段数量 ==="
awk '{print NF}' data.txt
详细解释:
-
NF
:Number of Fields,当前记录的字段数 -
对每行输出其字段数量
-
data.txt中每行都是3个字段
# 打印记录号
echo -e "\n=== 打印记录号 ==="
awk '{print NR}' data.txt
详细解释:
-
NR
:Number of Records,记录号(行号) -
从1开始递增
-
全局行号,跨文件累计
3.3.2 特殊变量
# 设置字段分隔符为冒号
echo "=== 使用冒号分隔符 ==="
awk -F: '{print $1, $7}' passwd
详细解释:
-
-F:
:设置输入字段分隔符为冒号 -
$1
:用户名 -
$7
:shell -
处理passwd文件格式
# 设置多个分隔符(逗号和空格)
echo -e "\n=== 使用多个分隔符 ==="
echo "name,age job,salary" | awk -F'[ ,]' '{print $1, $2, $3, $4}'
详细解释:
-
-F'[ ,]'
:使用正则表达式作为分隔符,逗号或空格 -
[ ,]
:字符集合,匹配逗号或空格 -
将混合分隔符的文本正确分割
# 查看特殊变量的值
echo -e "\n=== 查看特殊变量 ==="
awk '{print "NF=" NF ", NR=" NR ", FILENAME=" FILENAME}' data.txt | head -3
详细解释:
-
NF
:当前行字段数 -
NR
:当前记录号 -
FILENAME
:当前处理的文件名 -
字符串拼接输出
3.4.1 正则表达式模式
# 匹配包含特定模式的行
echo "=== 匹配包含'Engineer'的行 ==="
awk '/Engineer/ {print}' data.txt
详细解释:
-
/Engineer/
:正则表达式模式 -
只处理包含"Engineer"的行
-
模式匹配作为条件
# 匹配字段内容
echo -e "\n=== 匹配第一字段包含'J'的行 ==="
awk '$1 ~ /^J/ {print}' data.txt
详细解释:
-
$1 ~ /^J/
:第一字段匹配以J开头的正则 -
~
:匹配操作符 -
!~
:不匹配操作符 -
字段级别的正则匹配
# 不匹配 echo -e "\n=== 不匹配包含'Designer'的行 ===" awk '$3 !~ /Designer/ {print}' data.txt
详细解释:
-
$3 !~ /Designer/
:第三字段不包含"Designer" -
!~
:不匹配操作符 -
排除特定内容
# 行号范围
echo -e "\n=== 处理第3到第5行 ==="
awk 'NR>=3 && NR<=5 {print}' data.txt
详细解释:
-
NR>=3 && NR<=5
:行号在3到5之间 -
&&
:逻辑与 -
基于行号的范围选择
# 字段数量条件
echo -e "\n=== 字段数量等于3的行 ==="
awk 'NF==3 {print}' data.txt
详细解释:
-
NF==3
:字段数等于3的行 -
==
:等于比较 -
基于结构的筛选
3.4.2 关系表达式
# 数值比较
echo "=== 年龄大于30的员工 ==="
awk '$2 > 30 {print}' data.txt
详细解释:
-
$2 > 30
:第二字段(年龄)大于30 -
awk自动识别数字进行数值比较
-
不是字符串比较
# 字符串比较
echo -e "\n=== 职位是'Engineer'的员工 ==="
awk '$3 == "Engineer" {print}' data.txt
详细解释:
-
$3 == "Engineer"
:第三字段等于"Engineer" -
==
:字符串相等比较 -
区分大小写
# 复合条件
echo -e "\n=== 年龄大于30且职位包含'Engineer'的员工 ==="
awk '$2 > 30 && $3 ~ /Engineer/ {print}' data.txt
详细解释:
-
$2 > 30
:年龄大于30 -
&&
:逻辑与 -
$3 ~ /Engineer/
:职位包含Engineer -
多条件组合
3.5.1 print和printf
# 基本print
echo "=== 基本print ==="
awk '{print $1, $2}' data.txt
详细解释:
-
print
:输出字段,自动添加换行 -
$1, $2
:字段列表,用OFS分隔 -
简单的字段选择输出
# 格式化输出printf
echo -e "\n=== 格式化输出 ==="
awk '{printf "%-10s %3d %15s\n", $1, $2, $3}' data.txt
详细解释:
-
printf
:格式化输出,不自动换行 -
%-10s
:左对齐10字符宽字符串 -
%3d
:右对齐3字符宽整数 -
%15s
:右对齐15字符宽字符串 -
\n
:手动添加换行 -
精确控制输出格式
# printf格式说明符演示
echo -e "\n=== 不同格式输出 ==="
awk 'BEGIN {printf "整数: %d\n浮点数: %.2f\n字符串: %s\n", 42, 3.14159, "Hello"}'
详细解释:
-
BEGIN
:在处理任何输入前执行 -
%d
:十进制整数 -
%.2f
:保留2位小数的浮点数 -
%s
:字符串 -
演示各种格式说明符
3.5.2 变量和数组
# 用户定义变量
echo "=== 计算平均年龄 ==="
awk '{sum += $2; count++} END {print "Average age:", sum/count}' data.txt
详细解释:
-
sum += $2
:累加年龄 -
count++
:计数器递增 -
END
:所有输入处理后执行 -
计算平均值
# 数组操作
echo -e "\n=== 使用数组统计职位 ==="
awk '{positions[$3]++} END {for (pos in positions) print pos, positions[pos]}' data.txt
详细解释:
-
positions[$3]++
:以职位为键的关联数组,计数 -
END
:处理完成后 -
for (pos in positions)
:遍历数组 -
print pos, positions[pos]
:输出键值对 -
词频统计
# 数组排序
echo -e "\n=== 排序数组 ==="
awk '{arr[$1] = $2} END {n = asorti(arr, sorted); for (i=1; i<=n; i++) print sorted[i], arr[sorted[i]]}' data.txt
详细解释:
-
arr[$1] = $2
:姓名为键,年龄为值 -
asorti
:按索引排序,返回排序后的索引数组 -
for
循环输出排序结果 -
数组排序功能
3.5.3 控制结构
# if语句
echo "=== 使用if语句分类员工 ==="
awk '{if ($2 > 30) print $1, "Senior"; else print $1, "Junior"}' data.txt
详细解释:
-
if ($2 > 30)
:条件判断 -
print $1, "Senior"
:条件成立时执行 -
else
:否则执行 -
print $1, "Junior"
:条件不成立时执行 -
条件分支
# for循环
echo -e "\n=== for循环演示 ==="
awk 'BEGIN {for (i=1; i<=5; i++) print "Number:", i}'
详细解释:
-
BEGIN
:预处理块 -
for (i=1; i<=5; i++)
:C风格for循环 -
print "Number:", i
:循环体 -
生成序列
# while循环
echo -e "\n=== while循环演示 ==="
awk 'BEGIN {i=1; while (i<=3) {print "While loop:", i; i++}}'
详细解释:
-
while (i<=3)
:当条件成立时循环 -
{...}
:循环体,多条语句 -
i++
:循环变量递增 -
while循环结构
# for-in循环
echo -e "\n=== for-in循环处理字段 ==="
awk '{for (i=1; i<=NF; i++) print "Field " i ":", $i}' data.txt | head -6
详细解释:
-
for (i=1; i<=NF; i++)
:从1到字段数循环 -
$i
:第i个字段 -
动态访问字段