三剑客之awk
在 AWK 中,除了命令行参数(如 -v, -F,-f)这样的命令行参数外,还有许多 内置变量 和 特殊命令(如 RS, FS, OFS, NR 等),它们可以控制 AWK 的输入/输出处理逻辑。你提到的 NS 并不是 AWK 的标准变量,可能是笔误(应该是 RS 或 FS)。下面我会分类详细举例说明这些关键变量和命令:
1. 输入控制变量
这些变量影响 AWK 如何读取输入数据:
| 变量 | 作用 | 示例 |
|---|---|---|
RS (Record Separator) |
定义输入行的记录分隔符(默认 \n) |
awk 'BEGIN{RS=";"} {print $0}' |
FS (Field Separator) |
定义字段分隔符(默认空格/制表符) | awk 'BEGIN{FS=","} {print $1}' |
NF (Number of Fields) |
当前行的字段数量 | awk '{print NF, $0}' |
NR (Number of Records) |
当前处理的行号(累计所有文件) | awk '{print NR, $1}' |
FNR (File Number of Records) |
当前文件的行号(每个文件单独计数) | awk '{print FNR, $1}' file1 file2 |
示例:
# 用分号 `;` 代替换行符作为行分隔符
echo "a;b;c" | awk 'BEGIN{RS=";"} {print "Line", NR, ":", $0}'
输出:
Line 1 : a
Line 2 : b
Line 3 : c
2. 输出控制变量
这些变量控制 AWK 如何输出数据:
| 变量 | 作用 | 示例 |
|---|---|---|
ORS (Output Record Separator) |
输出行分隔符(默认 \n) |
awk 'BEGIN{ORS="---"} {print $0}' |
OFS (Output Field Separator) |
输出字段分隔符(默认空格) | awk 'BEGIN{OFS="|"}{print $1,$2}' |
OFMT (Output Format) |
数字输出的格式(默认 %.6g) |
awk 'BEGIN{OFMT="%.2f"; print 3.14159}' |
示例:
# 用 " | " 分隔字段,用 "---" 分隔行
echo -e "1 2\n3 4" | awk 'BEGIN{OFS=" | "; ORS="---\n"} {print $1,$2}'
输出:
1 | 2---
3 | 4---
3. 数据处理命令
这些命令用于 修改记录或字段:
| 命令 | 作用 | 示例 |
|---|---|---|
getline |
手动读取下一行 | awk '{getline; print $0}' |
sub() / gsub() |
替换字符串 | awk '{gsub(/foo/, "bar"); print}' |
split() |
分割字符串到数组 | awk '{split($0, arr, ","); print arr[1]}' |
length() |
计算字符串/数组长度 | awk '{print length($0)}' |
示例:
# 替换所有 "apple" 为 "orange"
echo "apple banana apple" | awk '{gsub(/apple/, "orange"); print}'
输出:
orange banana orange
4. 文件操作命令
| 命令 | 作用 | 示例 |
|---|---|---|
next |
跳过当前行,处理下一行 | awk '/skip/{next} {print}' |
exit |
立即退出 AWK | awk '{print NR; if(NR==3) exit}' |
system() |
执行 Shell 命令 | awk 'BEGIN{system("ls")}' |
示例:
# 跳过包含 "ignore" 的行
echo -e "hello\nignore this\nworld" | awk '/ignore/{next} {print}'
输出:
hello
world
5. 高级用法示例
(1) 多文件处理
awk '{print FILENAME, FNR, $0}' file1.txt file2.txt
输出:
file1.txt 1 line1
file1.txt 2 line2
file2.txt 1 lineA
...
(2) 计算列总和
echo -e "10\n20\n30" | awk '{sum+=$1} END{print "Total:", sum}'
输出:
Total: 60
(3) 提取 CSV 的特定列
echo "name,age,email" | awk -F ',' '{print $2}'
输出:
age
总结
- 输入控制:
RS,FS,NR,FNR,NF - 输出控制:
ORS,OFS,OFMT - 数据处理:
getline,sub/gsub,split,length - 流程控制:
next,exit,system()
这些变量和命令可以组合使用,例如:
awk 'BEGIN{FS=","; OFS="|"} NR>1 {print $1, $3}' data.csv
(从 CSV 文件第 2 行开始,用 | 分隔第 1 和第 3 列)
如果有特定需求(如解析日志、数据清洗),可以进一步优化脚本!
浙公网安备 33010602011771号