Awk入门
完成条件
Awk 脚本化与高级应用
Awk 不仅可以在命令行中执行,还可以编写成 独立脚本 并用于自动化任务。本章介绍如何 在 Shell 脚本中使用 Awk,以及 高级控制逻辑(如状态机)。
1. 在 Shell 脚本中运行 Awk
如果需要重复使用 Awk 程序,可以将其写入 Shell 脚本。
示例 1:逐行打印文件中的每个单词
创建 words
脚本
#!/bin/bash
awk '{c=split($0, s); for(n=1; n<=c; ++n) print s[n] }' $1
赋予可执行权限
chmod +x words
执行
./words input.txt
示例输入
Hello World!
Awk is powerful.
输出
Hello
World!
Awk
is
powerful.
可以在
vi
/vim
中调用
:%!words
这样可以将文本转换为逐个单词的列表。
2. 双倍行距与去除双倍空行
示例 2:双倍行距
#!/bin/bash
awk '{print; if (NF != 0) print ""}' -
在
vi
中调用
:%!double
效果:原文件的每一行都被增加了一行空行。
示例 3:去除双倍空行
方案
awk 'BEGIN {skip = 0}
skip == 0 {if (NF == 0) {skip = 1} else {print}; next}
skip == 1 {print; skip = 0; next}' input.txt
逻辑
- 变量
skip
记录是否跳过空行:- 遇到第一个空行时,
skip = 1
,跳过打印。 - 遇到第二个空行时,
skip = 0
,打印出来。
- 遇到第一个空行时,
- 保证单独的空行不会被删除。
示例输入
Line 1
Line 2
Line 3
示例输出
Line 1
Line 2
Line 3
3. 查找重复单词
需求:找出文本中 连续重复的单词。
方案
awk 'BEGIN { dups=0; w="xy-zzy" }
{ for( n=1; n<=NF; n++)
{ if ( w == $n ) { print w, "::", $0 ; dups = 1 } ; w = $n }
}
END { if (dups == 0) print "No duplicates found." }' input.txt
示例输入
And the result was also also that it failed.
示例输出
also :: And the result was also also that it failed.
w="xy-zzy"
初始化为不会出现在文本中的字符串。- 扫描每个单词,如果和上一个单词相同,则输出。
dups=1
标记是否存在重复单词,最后如果dups==0
则输出No duplicates found.
。
4. 变量在多行处理中的应用
示例 4:匹配特定值,并打印下一行
awk 'BEGIN {flag = 0}
$1 == 1000 {flag = 1; next}
flag == 1 {print; flag = 0; next}' input.txt
逻辑
- 如果行的第一列是
1000
,则标记flag = 1
并跳过当前行。 - 下一行被打印,之后
flag = 0
,防止多次匹配。
示例输入
999 DataA
1000 DataB
1111 DataC
2222 DataD
示例输出
1111 DataC
**示例 5:匹配 1000
并打印 后 5 行
awk 'BEGIN {counter = 0}
$1 == 1000 {counter = 5; next}
counter > 0 {print; counter--; next}' input.txt
逻辑
- 遇到
$1 == 1000
时,counter = 5
。 - 之后的 5 行都被打印,
counter--
,直到counter = 0
。
示例输入
500 DataX
1000 StartHere
2000 Data1
3000 Data2
4000 Data3
5000 Data4
6000 Data5
7000 Data6
示例输出
2000 Data1
3000 Data2
4000 Data3
5000 Data4
6000 Data5
5. Awk 状态机(State Machine)
如果需要在不同状态间切换,可以使用 状态机(State Machine) 记录当前状态。
示例 6:执行 5 个不同操作
awk 'BEGIN {state = 0}
$1 == "START" {state = 1; next}
state == 1 {print "Step 1:" $0; state = 2; next}
state == 2 {print "Step 2:" $0; state = 3; next}
state == 3 {print "Step 3:" $0; state = 4; next}
state == 4 {print "Step 4:" $0; state = 5; next}
state == 5 {print "Final Step:" $0; state = 0; next}' input.txt
示例输入
Hello World
START
Data A
Data B
Data C
Data D
Data E
More Data
示例输出
Step 1:Data A
Step 2:Data B
Step 3:Data C
Step 4:Data D
Final Step:Data E
state
变量控制执行步骤- 遇到
START
时,进入state=1
- 依次执行
state=1
到state=5
- 执行
Final Step
后回到state=0
总结
任务 | Awk 代码 |
---|---|
Shell 脚本调用 Awk | awk '{print}' $1 |
双倍行距 | awk '{print; if (NF != 0) print
""}' |
去除多余空行 | awk 'BEGIN {skip=0} skip==0 {if
(NF==0) {skip=1} else {print}; next} skip==1 {print; skip=0;
next}' |
查找重复单词 | awk 'BEGIN {dups=0; w="xy-zzy"}
{for(n=1; n<=NF; n++) {if(w==$n){print w,"::",$0; dups=1} w=$n}}
END {if(dups==0) print "No duplicates found."}' |
匹配 1000 并打印下一行 |
awk 'BEGIN {flag=0} $1==1000 {flag=1;
next} flag==1 {print; flag=0; next}' |
匹配 1000 并打印后 5 行 |
awk 'BEGIN {counter=0} $1==1000
{counter=5; next} counter>0 {print; counter--; next}' |
状态机示例 | awk 'BEGIN {state=0} $1=="START"
{state=1; next} state==1 {print "Step 1:", $0; state=2; next}' |
🚀 下一章,我们将学习 Awk 的文件处理和数据分析!
最后修改: 2025年01月30日 星期四 01:31