数组的问题:
在定义数组的时候:实例:
awk 数组中把第一个域归纳为数组,第二个域归纳成数组时需要用到第一个域的格式或者归纳成$0
如:
qqfile
11235334: 13443253456
11235335: 13443253457
11235336: 13443253458
11235333: 13443253458
11235336: 13443253459
对一个域计数:a[$1]++ …然后对于第二个域,如果有格式的话:如:
输出格式:
11235334
2
13443253456
13443253452
数组格式就要写成:b[$1]=b[$1]”\n”$2 或者b[$1]=b[$1]RS $2 如果不需要设置格式,则只需要让b[$1]=$0 即可将字符数组赋值。。
a[index]++ 由++运算符说明a数组是一个数字数组,而如果没有给出则说明a数组为字符数组
awk -F'[: ]' '{a[$1]++;b[$1]=b[$1]"\n"$3;}END{for (QQ in a){print QQ ,a[QQ],b[QQ]}}' qqfile
此文件中END 前的部分数组表示计数,END后面的内容对当前文件输入结束时执行一次。
注意:如果一个数组表示字符串,则b[QQ]将等于个字符串值。上述中
b[11235334]=“13443253456”
并非b[11235334]=1之类的计数内容
另外,非常重要的一点:此例中b[$1]=b[$1]RS $2 此数组初始化:b[$1]就等于$2,
例如:
有一个文件cat abc
1 10
3 20
1 50
5 20
20 46
5 40
想实现这样的功能:
第一列按照1 3 5 10 20 排序,第二列进行求和.
如果第一列的值不存在,则第二列补充为0.
即最后想要的的结果是:
1 60
3 20
5 60
10 0
20 46
请教怎么解决?
答案1:awk '{a[$1]+=$2;b[$1]=$1;}END{x=asort(b);for(i=1;i<=x;i++)print b[i],a[b[i]]}'
答案2:
echo "1 10
3 20
1 50
5 20
20 46
5 40" |awk 'NF==2{a[$1]+=$2;next}{print $1,a[$1]?a[$1]:"0"}' - <(echo "1
3
5
10
20")
1 60
3 20
5 60
10 0
20 46
在定义中:a[$1]+=$2 其实也就是a[$1]=a[$1]+$2。在实际操作当中awk ‘{a[$1];print a[$1]}’ 则打印为空,若:awk ‘{a[$1]=$1;print a[$1]}’则会打印$1 ,若是: awk ‘{a[$1]+=$2;print a[$1]}’ 在这里: a[$1]+=$2实际是将$2赋值给以$1为下标的数组a[$1],其实也就是:
1 10 a[“1”]=10
3 20 a[“3”]=20
1 50 a[“1”]=50
5 20 a[“5”]=20
20 46 a[“20”]=46
也就相当于a[$1]=$2 ,而a[$1]=a[$1]+$2 其实也就是让第一列相同的,让$2相加
同理:对于:a[$1]=a[$1] FS RS RT $2 之类也就不难理解了.
RS输入记录分隔符,默认是回车
RT记录终结符号
注意:确保整个awk命令用单引号括起来;确保命令内所有引号成对出现;确保用花括号括起动作语句,用圆括号括起条件语句;
在BEGIN阶段给变量赋值要用{}括起来
注意=是赋值==是等于
为增加列数进行结果统计,使用符号+= .增加的结果赋给符号左边的变量,增加到变量的域在符号右边。例如将$1加入变量total ,表达式为:total+=$1,列值增加,用来统计文件总数,输出结果
例如:awk '(tot+=$6);END {print "Club student total points : " tot }' test
将第六列求和!tot=第一行的$6+第二行的$6....
计算文件的大小 : ls -l | awk '{print $9 "\t" $5} {tot+=$5} END {print "total KB: "tot} '
awk 中的变量都都不用加$
awk -v OFS="|" '{print $1 OFS $2}' -v 给OFS赋值 -v是在给变量OFS 赋值
a[$1]=a[$1]RS RS $2 ## 给a数组赋值 不能加引号
0 与 "0" 差在哪
以下3种情况是“假”,其他情况都为“真”
1) 数字 0
2) 空字符串
3) 未定义的值
ly5066113@ubuntu:~$ awk 'BEGIN{if(0) print "true";else print "false"}'
false
ly5066113@ubuntu:~$ awk 'BEGIN{if("0") print "true";else print "false"}'
true
一个被大家称为月经的问题,awk如何去重?
awk '! a[$0] ++'
awk的一个特性:
awk 会根据语境来给未定义的变量赋初始值
ly5066113@ubuntu:~$ awk 'BEGIN{print a "" 1}'
1
ly5066113@ubuntu:~$ awk 'BEGIN{print a + 1}'
1
awk 中所有不加引号的字符或者字符串都会当作变量处理,数字除外!
对于未定义的变量,如果要进行字符串操作,会被赋成空字符串 ""
如果要进行数学运算,会被赋成数字 0
上面的代码 ! a[$0] ++ 等价于 if(! a[$0] ++) print $0
对于首次出现的记录,a[$0]的值是未定义的,由于后面的 ++ 是数学计算,所以a[$0]会被赋值成数字0
也是由于 ++ 操作符,会先取值,再计算,所以对于第一行记录实际上是if(! 0) print $0
! 是取反,0 是假,! 0 就是真,那么就会执行后面的 print $0
对于后面出现的重复记录,a[$0] 经过 ++ 的计算已经变为 1、2、3 。。。
而 ! 1 ! 2 ! 3 ... 都为假,不会打印。
NR FNR的区别
ly5066113@ubuntu:~$ awk '{print FILENAME,"NR="NR,"FNR="FNR,$0}' a.txt b.txt c.txt
a.txt NR=1 FNR=1 a
a.txt NR=2 FNR=2 b
a.txt NR=3 FNR=3 c
b.txt NR=4 FNR=1 d
b.txt NR=5 FNR=2 e
b.txt NR=6 FNR=3 f
c.txt NR=7 FNR=1 g
c.txt NR=8 FNR=2 h
c.txt NR=9 FNR=3 i
NR是awk处理的总记录数,无论多少个文件,是一直累加的而FNR是awk处理当前文件的记录数,当文件变化的时候是重新记数的
ARGV 是一个数组,它记录着命令行的所有参数的值
ARGC 是命令行参数的个数,(不包括-F、-v之类的awk参数)
ARGIND 是ARGV数组的索引值,从0到ARGC-1
awk 空行 length()这个函数 判断 length($0)==0 说明是空行
awk 的结构:
pattern{Action} ,
如何处理: 先判断该pattern的值,若patten判断后的值为true(或不为0的数字,或不是空的字符串),则执行pattern所对应的action,反之,若pattern之值不为true,则awk将不执行该pattern所对应的action
语法中若缺少pattern部分,表示无条件执行这个action
如果文件a中包含文件b,则将文件b的记录打印出来输出到c文件里
文件a:
10/05766798607,11/20050325191329,29/0.1,14/05766798607
10/05767158557,11/20050325191329,29/0.08,14/05767158557
文件b:
05766798607
05766798608
05766798609
通过文件a和文件b对比,导出这样的文件出来.
10/05766798607,11/20050325191329,29/0.1,14/05766798607
本人查了很多网上的答案都是错误码的
正确答案应该:
方法:
awk –F’[/,]’ ‘NR=FNR{a[$1]}NR>FNR{if($2 in a) print $0 > c}’ b a
不能写成a[$0]
awk 会先判断(Evaluate) 该 Pattern 的值, 若 Pattern 判断后的值为true (或不为0的数字,或不是空的字符串), 则 awk将执行该 Pattern 所对应的 Actions.反之, 若 Pattern 之值不为 true,
则awk将不执行该 Pattern所对应的 Actions.
evaluate 评价
有两个文件 1.txt和2.txt,内容如下:
txt
a 0
c 0
b 0
f 0
txt
a 1
c 2
b 4
d m
e 3
f 2
如果把2.txt中第一列和1.txt中第一列匹配的字符所在的行附加到1.txt后面,得到的结果是:
a 0 1
c 0 2
b 0 4
f 0 2
[root@danoolive simple]# awk 'NR==FNR{a[$1]=a[$1] FS $2}NR>FNR{if($1 in a) print $1 a[$1]" "$2}' 1.txt 2.txt
a 0 1
c 0 2
b 0 4
f 0 2
[root@danoolive simple]# awk 'NR==FNR{a[$1]=$0}NR>FNR{if($1 in a) print a[$1]" "$2}' 1.txt 2.txt
a 0 1
c 0 2
b 0 4
f 0 2
awk 如何处理{ Actions } 的语法?(缺少Pattern部分)
有时语法 Pattern { Actions }中, Pattern 部分被省略,只剩 {Actions}.这种情形表示 "无条件执行这个 Actions".
{a[$1]} 无条件执行:将$1给数组a
该贴被lusxingbao编辑于2013-3-17 20:29:55
该贴被lusxingbao编辑于2013-3-17 20:31:40
该贴被lusxingbao编辑于2013-3-17 20:33:31