说明:awk命令和sed命令一样,也是逐行扫描文件的,从第一行到最后一行,寻找匹配特定模板的行,并在这些行上运行“选择”动作。如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上。如果一个动作没有模板,所有被动作指定的行都被处理。
1、awk的基本格式:
awk 'pattern' filename
awk '{action}' filename
awk 'pattern {action}' filename
具体应用方式分别见如下三个用例:
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
Tom
Mary
Sally
Billy
转码 含义
换行
回车
制表符
Month: Oct
Year: 2011
Have a nice day, Sally Chang!
1.25 0.12
%c 打印单个ASCII字符。 printf("The character is %c. ",x) The character is A.
%d 打印十进制数。 printf("The boy is %d years old. ",y) The boy is 15 years old.
%e 打印用科学记数法表示的数。 printf("z is %e. ",z) z is 2.3e+01.
%f 打印浮点数。 printf("z is %f. ",z) z is 2.300000
%o 打印八进制数。 printf("y is %o. ",y) y is 17.
%s 打印字符串。 printf("The name of the culprit is %s. ",$1); The name of the culprit is Bob Smith.
%x 打印十六进制数。 printf("y is %x. ",y) y is f.
echo "Linux" | awk '{printf "|%-15s| ", $1}'
|Linux |
# %-15s表示保留15个字符的空间,同时右对齐。
echo "Linux" | awk '{printf "|%15s| ", $1}'
| Linux|
The name is Tom ID is 4424
The name is Mary ID is 5346
The name is Sally ID is 1654
The name is Billy ID is 1683
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
1 Tom Jones 4424 5/12/66 543354
2 Mary Adams 5346 11/4/63 28765
3 Sally Chang 1654 7/22/54 650000
4 Billy Black 1683 9/23/44 336500
Tom Jones 4424 5/12/66 543354 5
Mary Adams 5346 11/4/63 28765 5
Sally Chang 1654 7/22/54 650000 5
Billy Black 1683 9/23/44 336500 5
cat employees
Tom Jones:4424:5/12/66:543354
Mary Adams:5346:11/4/63:28765
Sally Chang:1654:7/22/54:650000
Billy Black:1683:9/23/44:336500
Tom Jones?4424
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
awk '$3 < 4000 && /Sally/ {print}' employees
Sally Chang 1654 7/22/54 650000
" ~ " 用来在记录或者域内匹配正则表达式。
#显示所有第一个域匹配Bill或bill的行。
awk '$1 ~ /[Bb]ill/' employees
Billy Black 1683 9/23/44 336500
#显示所有第一个域不匹配Bill或bill的行,其中!~表示不匹配的意思。
awk '$1 !~ /[Bb]ill/' employees
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
5. awk的基本应用实例:
cat testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
#打印所有以north开头的行。
awk '/^north/' testfile
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
#打印所有以so和no开头的行。
awk '/^(no|so)/' testfile
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
#第五个域字段匹配包含.(点),后面是7-9的数字。
awk '$5 ~ /.[7-9]+/' testfile
southwest SW Lewis Dalsass 2.7 .8 2 18
central CT Ann Stephens 5.7 .94 5 13
#第八个域以两个数字结束的打印。
awk '$8 ~ /[0-9][0-9]$/{print $8}' testfile34
23
18
15
17
20
13
十. awk表达式功能:
1. 比较表达式:
比较表达式匹配那些只在条件为真时才运行的行。这些表达式利用关系运算符来比较数字和字符串。见如下awk支持的条件表达式列表:
运算符 含义 例子
< 小于 x < y
<= 小于等于 x <= y
== 等于 x == y
!= 不等于 x != y
>= 大于等于 x >= y
> 大于 x > y
~ 匹配 x ~ /y/
!~ 不匹配 x !~ /y/
cat employees
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
#打印第三个域等于5346的行。
awk '$3 == 5346' employees
Mary Adams 5346 11/4/63 28765
#打印第三个域大于5000的行的第一个域字段。
awk '$3 > 5000 {print $1}' employees
Mary
#打印第二个域匹配Adam的行。
awk '$2 ~ /Adam/' employess
Mary Adams 5346 11/4/63 28765
2. 条件表达式:
条件表达式使用两个符号--问号和冒号给表达式赋值: conditional expression1 ? expression2 : expressional3,其逻辑等同于C语言中的条件表达式。其对应的if/else语句如下:
{
if (expression1)
expression2
else
expression3
}
cat testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
awk 'NR <= 3 {print ($7 > 4 ? "high "$7 : "low "$7) }' testfile
low 3
high 5
low 2
3. 数学表达式:
运算可以在模式内进行,其中awk将所有的运算都视为浮点运算,见如下列表:
运算符 含义 例子
+ 加 x + y
- 减 x - y
* 乘 x * y
/ 除 x / y
% 取余 x % y
^ 乘方 x ^ y
#如果记录包含正则表达式southern,第五个域就加10并打印。
awk '/southern/{print $5 + 10}' testfile
15.1
#如果记录包含正则表达式southern,第八个域除以2并打印。
awk '/southern/{print $8 /2 }' testfile
7.5
4. 逻辑表达式:
见如下列表:
运算符 含义 例子
&& 逻辑与 a && b
|| 逻辑或 a || b
! 逻辑非 !a
#打印出第八个域的值大于10小于17的记录。
awk '$8 > 10 && $8 < 17' testfile
southern SO Suan Chin 5.1 .95 4 15
central CT Ann Stephens 5.7 .94 5 13
#打印第二个域等于NW,或者第一个域匹配south的行的第一、第二个域。
awk '$2 == "NW" || $1 ~ /south/ {print $1,$2}' testfile
northwest NW
southwest SW
southern SO
southeast SE
#打印第八个域字段不大于13的行的第八个域。
awk '!($8 > 13) {print $8}' testfile
3
9
13
5. 范围模板:
范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现,第一个模板的下一次出现到第一个模板的下一次出现等等。如果第一个模板匹配而第二个模板没有出现,awk就显示到文件末尾的所有行。
#打印以western开头到eastern开头的记录的第一个域。
awk '/^western/,/^eastern/ {print $1}' testfile
western WE
southwest SW
southern SO
southeast SE
eastern EA
6. 赋值符号:
#找到第三个域等于Ann的记录,然后给该域重新赋值为Christian,之后再打印输出该记录。
awk '$3 == "Ann" { $3 = "Christian"; print}' testfile
central CT Christian Stephens 5.7 .94 5 13
#找到包含Ann的记录,并将该条记录的第八个域的值+=12,最后再打印输出。
awk '/Ann/{$8 += 12; print $8}' testfile
25