试一下手:
先看先原始的操作文本:
[root@hadoop ~]# cat tour.txt
air:23;hotel:34;nation:CHINA
air:35;hotel:46;nation:USA
air:36;hotel:47;nation:USA
air:26;hotel:37;nation:CHINA
air:33;hotel:44;nation:USA
air:34;hotel:45;nation:USA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
1. 指定分隔符,通过某个域值过滤行
[root@hadoop ~]# awk 'BEGIN{FS="[:;]"} $6=="CHINA"' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
另一种写法:
[root@hadoop ~]# awk -F'[;:]' '$6=="CHINA"' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
如果只想打印出某个域值:
[root@hadoop ~]# awk 'BEGIN{FS="[:;]"}{print $6}' tour.txt
CHINA
USA
USA
CHINA
USA
USA
CHINA
CHINA
2.上面的第一种方法给出在执行action前执行的操作即是改变输入分隔符,现在来改变输出分隔符
[root@hadoop ~]# awk 'BEGIN{FS="[;:]";OFS="%"}{print $1,$3}' tour.txt
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
3.正则匹配
[root@hadoop ~]# awk 'BEGIN{FS="[;:]";OFS="%"} $6~/[Cc][Hh][Ii][Nn][aA]/' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
4.替换原文的域值:
[root@hadoop ~]# awk 'BEGIN{FS="[;:]";OFS="|"}{$1="AIR";$3="HOTEL";print}' tour.txt
AIR|23|HOTEL|34|nation|CHINA
AIR|35|HOTEL|46|nation|USA
AIR|36|HOTEL|47|nation|USA
AIR|26|HOTEL|37|nation|CHINA
AIR|33|HOTEL|44|nation|USA
AIR|34|HOTEL|45|nation|USA
AIR|25|HOTEL|36|nation|CHINA
AIR|24|HOTEL|35|nation|CHINA
4. 综合运用END,和一些简单的表达式
[root@hadoop ~]# awk 'BEGIN{FS="[;:]"};airsum+=$2;END{print airsum}' tour.txt
air:23;hotel:34;nation:CHINA
air:35;hotel:46;nation:USA
air:36;hotel:47;nation:USA
air:26;hotel:37;nation:CHINA
air:33;hotel:44;nation:USA
air:34;hotel:45;nation:USA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
236
再试着把airsum+=$2 加上大括号,
[root@hadoop ~]# awk 'BEGIN{FS="[;:]"};{airsum+=$2};END{print airsum}' tour.txt
236
结果是显而易见的
对应的看下以下三种情况:
4.1
[root@hadoop ~]# awk -F'[;:]' '{$2<27 print $2}' tour.txt
awk: {$2<27 print $2}
awk: ^ syntax error
4.2 这种情况就比较玩味的,在处理的时候先用模式匹配继而由操作print,比如说第一行,先判断23是否小于27,是的,因为没有后续
的action所以输出整行,在print$2,第二行的时候 35>27所以不输出整行
[root@hadoop ~]# awk -F'[;:]' '$2<27;{ print $2}' tour.txt
air:23;hotel:34;nation:CHINA
23
35
36
air:26;hotel:37;nation:CHINA
26
33
34
air:25;hotel:36;nation:CHINA
25
air:24;hotel:35;nation:CHINA
24
4.3这是先用模式去过滤行
[root@hadoop ~]# awk -F'[;:]' '$2<27 { print $2}' tour.txt
23
26
25
24
这种情况类似:
[root@hadoop ~]# awk -F'[;:]' '{if($2<27) print $2}' tour.txt
23
26
25
24
4.4,这种情况是好理解的,因为$2<27被当做了一个普通的操作而不是去匹配行的内容
[root@hadoop ~]# awk -F'[;:]' '{$2<27;print $2}' tour.txt
23
35
36
26
33
34
25
24
其实,在AWK中任何的语句都是由模式和动作构成,模式可以是正则表达式或者其他的判断用来约束动作的前提条件,如果省略模式则动作时刻保持执行状态
再看下使用条件判断的情况:
[root@hadoop ~]# awk 'BEGIN{FS="[;:]"};{if($6=="CHINA"){airsum+=$2;hotelsum+=$4}};END{print "air total is:", airsum,"
hotel total is:",hotelsum}' tour.txt
air total is: 98 hotel total is: 142
5.合并文件
[root@hadoop ~]# awk '{print FILENAME,$0}' tour.txt tour3.txt>tour4.txt
这类似于cat tour.txt tour3.txt >tour4.txt
但是cat不能像awk一样在tour4.txt加入来源文件的文件名
6. 调用管道数据
[root@hadoop ~]# awk 'BEGIN{"echo weihongrao"|getline d;print d}'
weihongrao
[root@hadoop ~]# awk 'BEGIN{"date"|getline d;print d}'
Wed Sep 4 03:42:31 EDT 2013
7.利用循环处理
[root@hadoop ~]# awk -F"[;:]" '{for(i=1;i<NF;i++){print $i}}' tour.txt
等价
[root@hadoop ~]# awk -F'[;:]' '{i=1;while(i<NF){print $i;i++}}' tour.txt
8.[root@hadoop ~]# awk -F'[;:]' '$2<=30{print $0}' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
[root@hadoop ~]# awk -F'[;:]' '$2<=30{print $0}' tour.txt>newtour.txt
[root@hadoop ~]# cat newtour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
先看先原始的操作文本:
[root@hadoop ~]# cat tour.txt
air:23;hotel:34;nation:CHINA
air:35;hotel:46;nation:USA
air:36;hotel:47;nation:USA
air:26;hotel:37;nation:CHINA
air:33;hotel:44;nation:USA
air:34;hotel:45;nation:USA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
1. 指定分隔符,通过某个域值过滤行
[root@hadoop ~]# awk 'BEGIN{FS="[:;]"} $6=="CHINA"' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
另一种写法:
[root@hadoop ~]# awk -F'[;:]' '$6=="CHINA"' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
如果只想打印出某个域值:
[root@hadoop ~]# awk 'BEGIN{FS="[:;]"}{print $6}' tour.txt
CHINA
USA
USA
CHINA
USA
USA
CHINA
CHINA
2.上面的第一种方法给出在执行action前执行的操作即是改变输入分隔符,现在来改变输出分隔符
[root@hadoop ~]# awk 'BEGIN{FS="[;:]";OFS="%"}{print $1,$3}' tour.txt
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
air%hotel
3.正则匹配
[root@hadoop ~]# awk 'BEGIN{FS="[;:]";OFS="%"} $6~/[Cc][Hh][Ii][Nn][aA]/' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
4.替换原文的域值:
[root@hadoop ~]# awk 'BEGIN{FS="[;:]";OFS="|"}{$1="AIR";$3="HOTEL";print}' tour.txt
AIR|23|HOTEL|34|nation|CHINA
AIR|35|HOTEL|46|nation|USA
AIR|36|HOTEL|47|nation|USA
AIR|26|HOTEL|37|nation|CHINA
AIR|33|HOTEL|44|nation|USA
AIR|34|HOTEL|45|nation|USA
AIR|25|HOTEL|36|nation|CHINA
AIR|24|HOTEL|35|nation|CHINA
4. 综合运用END,和一些简单的表达式
[root@hadoop ~]# awk 'BEGIN{FS="[;:]"};airsum+=$2;END{print airsum}' tour.txt
air:23;hotel:34;nation:CHINA
air:35;hotel:46;nation:USA
air:36;hotel:47;nation:USA
air:26;hotel:37;nation:CHINA
air:33;hotel:44;nation:USA
air:34;hotel:45;nation:USA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
236
再试着把airsum+=$2 加上大括号,
[root@hadoop ~]# awk 'BEGIN{FS="[;:]"};{airsum+=$2};END{print airsum}' tour.txt
236
结果是显而易见的
对应的看下以下三种情况:
4.1
[root@hadoop ~]# awk -F'[;:]' '{$2<27 print $2}' tour.txt
awk: {$2<27 print $2}
awk: ^ syntax error
4.2 这种情况就比较玩味的,在处理的时候先用模式匹配继而由操作print,比如说第一行,先判断23是否小于27,是的,因为没有后续
的action所以输出整行,在print$2,第二行的时候 35>27所以不输出整行
[root@hadoop ~]# awk -F'[;:]' '$2<27;{ print $2}' tour.txt
air:23;hotel:34;nation:CHINA
23
35
36
air:26;hotel:37;nation:CHINA
26
33
34
air:25;hotel:36;nation:CHINA
25
air:24;hotel:35;nation:CHINA
24
4.3这是先用模式去过滤行
[root@hadoop ~]# awk -F'[;:]' '$2<27 { print $2}' tour.txt
23
26
25
24
这种情况类似:
[root@hadoop ~]# awk -F'[;:]' '{if($2<27) print $2}' tour.txt
23
26
25
24
4.4,这种情况是好理解的,因为$2<27被当做了一个普通的操作而不是去匹配行的内容
[root@hadoop ~]# awk -F'[;:]' '{$2<27;print $2}' tour.txt
23
35
36
26
33
34
25
24
其实,在AWK中任何的语句都是由模式和动作构成,模式可以是正则表达式或者其他的判断用来约束动作的前提条件,如果省略模式则动作时刻保持执行状态
再看下使用条件判断的情况:
[root@hadoop ~]# awk 'BEGIN{FS="[;:]"};{if($6=="CHINA"){airsum+=$2;hotelsum+=$4}};END{print "air total is:", airsum,"
hotel total is:",hotelsum}' tour.txt
air total is: 98 hotel total is: 142
5.合并文件
[root@hadoop ~]# awk '{print FILENAME,$0}' tour.txt tour3.txt>tour4.txt
这类似于cat tour.txt tour3.txt >tour4.txt
但是cat不能像awk一样在tour4.txt加入来源文件的文件名
6. 调用管道数据
[root@hadoop ~]# awk 'BEGIN{"echo weihongrao"|getline d;print d}'
weihongrao
[root@hadoop ~]# awk 'BEGIN{"date"|getline d;print d}'
Wed Sep 4 03:42:31 EDT 2013
7.利用循环处理
[root@hadoop ~]# awk -F"[;:]" '{for(i=1;i<NF;i++){print $i}}' tour.txt
等价
[root@hadoop ~]# awk -F'[;:]' '{i=1;while(i<NF){print $i;i++}}' tour.txt
8.[root@hadoop ~]# awk -F'[;:]' '$2<=30{print $0}' tour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA
[root@hadoop ~]# awk -F'[;:]' '$2<=30{print $0}' tour.txt>newtour.txt
[root@hadoop ~]# cat newtour.txt
air:23;hotel:34;nation:CHINA
air:26;hotel:37;nation:CHINA
air:25;hotel:36;nation:CHINA
air:24;hotel:35;nation:CHINA