[转帖]关于awk sed 的实例_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3503 | 回复: 0   主题: [转帖]关于awk sed 的实例        下一篇 
root
注册用户
等级:中尉
经验:470
发帖:31
精华:1
注册:2013-2-22
状态:离线
发送短消息息给root 加好友    发送短消息息给root 发消息
发表于: IP:您无权察看 2013-2-28 10:26:33 | [全部帖] [楼主帖] 楼主

数组的问题:
在定义数组的时候:实例:
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




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论