Awk入门
完成条件
字段与文本块(Fields and Blocks)
Awk 的字符串搜索不仅限于整行匹配,还可以限定搜索范围,例如只匹配特定的字段或一组连续的行。
1. 限定字段搜索
我们可以限定搜索范围,使其只在特定字段中进行匹配。例如:
$1 ~ /^France$/
匹配第一列($1) 等于 "France"
的行,而:
$1 !~ /^Norway$/
匹配第一列($1) 不等于 "Norway"
的行。
2. 匹配文本块
Awk 允许匹配一组连续的行,可以使用两个搜索模式,分别匹配起始行和结束行:
/^Ireland/,/^Summary/
- 匹配从 "Ireland" 开头的行,一直到**"Summary" 开头的行**。
- 如果找不到
"Summary"
,那么**"Ireland" 之后的所有行都会被匹配**。
示例:
Ireland history
Ireland is famous for its culture
Dublin is the capital
Summary of Ireland’s population
匹配到的内容:
Ireland history
Ireland is famous for its culture
Dublin is the capital
Summary of Ireland’s population
3. 不是所有搜索模式都是正则表达式
Awk 的搜索模式可以是其他表达式,不一定是正则表达式。
3.1 按行号匹配
NR == 10
匹配第 10 行。NR
变量表示当前处理的行号(从 1 开始计数)。
匹配第 10 到 20 行:
NR == 10, NR == 20
4. 比较运算符
Awk 支持多种比较运算符:
运算符 | 作用 |
---|---|
< |
小于 |
<= |
小于等于 |
== |
等于 |
!= |
不等于 |
>= |
大于等于 |
> |
大于 |
~ |
匹配正则表达式 |
!~ |
不匹配正则表达式 |
示例:
NF == 0
匹配空行(字段数为 0)。
$1 == "France"
匹配第一列($1) 为 "France"
的行。
$1 ~ /^France$/
效果相同,但这里使用正则表达式,必须加 ^
和 $
来匹配完整单词。
5. 逻辑运算符
可以使用 &&
(AND)和 ||
(OR) 组合多个搜索模式。
示例:
((NR >= 30) && ($1 == "France")) || ($1 == "Norway")
- 匹配第 30 行之后的
France
- 或者匹配所有
Norway
如果 France
在前 30 行,则不会匹配,而 Norway
总是匹配。
6. 处理字段为数字还是字符串
Awk 是弱类型(Weakly-Typed) 语言,变量可存储数字或字符串,Awk 会自动决定如何处理它们。
$1 == 100
- 匹配第一列等于
100
的行。
$1 < 100
- 如果
$1
是数字,正常比较。 - 如果
$1
是字符串,Awk 会把它作为字符串,导致比较变得不可预测。
示例:
awk 'BEGIN {print ("100" < "50")}'
输出:
1 (因为字符串 "100" 按字母序比 "50" 小)
结论:
- 数字比较没问题
- 字符串比较可能导致错误
如何确保 $1
是数字
可以使用 数值运算 强制转换:
(($1 + 0) == $1) && ($1 > 100)
- 如果
$1
是数字,$1 + 0
仍然是数字,比较正常。 - 如果
$1
是文本,Awk 会把$1
解释为 0,然后(0 == $1)
为假,避免错误比较。
示例:
awk 'BEGIN {x="Hello"; print ((x+0) == x)}'
输出:
0 (字符串 "Hello" 不是数字)
7. 练习
-
打印少于 5 个单词的行,但忽略以
*
开头的行awk 'NF < 5 && $1 !~ /^\*/'
-
打印所有以数字开头的行
awk '$1 ~ /^[0-9]/'
-
检查编号错误的行
- 假设
data.txt
是编号的文本:1. First line 2. Second line 4. Fourth line (Wrong) 5. Fifth line
- 代码:
awk '{ if ($1+0 != NR) print "Incorrect line:", NR, "->", $0 }' data.txt
- 输出:
Incorrect line: 3 -> 4. Fourth line (Wrong)
- 假设
结论
- 可以限制搜索范围到某个字段(
$1 ~ /France/
)。 - 可以匹配文本块(
/^Start/,/^End/
)。 - 可以基于行号匹配(
NR == 10
)。 - 可以使用比较运算符(
<, ==, ~
)。 - 可以使用逻辑运算符(
&&, ||
)。 - 数字和字符串的比较需要小心,可以使用
($1 + 0) == $1
进行数值验证。
在下一章,你将学习更多关于 字符串和数值处理 的高级技巧!
最后修改: 2025年01月30日 星期四 01:12