也是awk合并文件的问题。求助求助啊。。。。大牛
martin 125
mary 362
jerry 332
file 2:
martin 133
mary 365
jerry 336
想要的结果
martin 125 133 258
mary 362 365 727
jerry 332 336 668
比较第一列相等后将$3 $4 ($4=$2+$3) 添加进file 1
网上找了好多办法只写出awk 'NR==FNR{a[$1]=$2;next}NR>FNR 后面怎么也写不出了。求助啊。可增加悬赏 展开
不好意思,最近没上网,
刚刚看到你的留言,
你这个问题只写了匹配到的情况;
如果file1 和file2里的第一列都是一一对应的,
可以直接用join函数,
24getU 写的就是正确的:
join fil1.txt fil2.txt|awk '{print $0,$2+$3}'
如果类似①(file1和file2第一列不一定一一对应):
file 1: file 2: 或者 file 1: file 2
martin 125 martin 133 martin 125 martin 133
mary 362 mary 365 mary 362 mary 365
jerry 332 jerry 336 jerry 332 jerry 336
lily 200 lily 200
②(file1或file2中存在第一列重复的数据):
file 1: file 2:
martin 125 martin 155
martin 203 lily 75
mary 222 lily 222
jerry 111
建议用下面三条命令:
(没有匹配到的写0, 每个文件中重复的数据自行相加
1> 得到file1和file2中所有名字, 写到临时文件name_temp:
awk '{print $1}' file1 file2 | sort -u > name_temp
2> 用一条awk 语句得到输出结果, 若要写到结果文件, 在语句最后重定向一下
awk 'FILENAME==ARGV[1]{name[NR]=$1;a[NR]=0;b[NR]=0}
FILENAME==ARGV[2]{for(i=1;i<=length(name);i++){if(name[i]==$1){a[i]+=$2}}}
FILENAME==ARGV[3]{for(j=1;j<=length(name);j++){if(name[j]==$1){b[j]+=$2}}}
END{for(k=1;k<=length(name);k++){print name[k],a[k],b[k],a[k]+b[k]}}' name_temp file1 file2
3> 删除临时文件name_temp:
rm name_temp
语句整合到一个脚本里方便些:
格式化一下输出(字段长度根据实际情况设定):
#!/bin/sh
awk '{print $1}' file1 file2 | sort -u > name_temp
awk 'FILENAME==ARGV[1]{name[NR]=$1;a[NR]=0;b[NR]=0}
FILENAME==ARGV[2]{for(i=1;i<=length(name);i++){if(name[i]==$1){a[i]+=$2}}}
FILENAME==ARGV[3]{for(j=1;j<=length(name);j++){if(name[j]==$1){b[j]+=$2}}}
END{for(k=1;k<=length(name);k++){
printf("%-10s%10d%10d%10d\n",name[k],a[k],b[k],a[k]+b[k])}}'
name_temp file1 file2 >result.txt
rm name_temp
对于先前说的①②两种情况,
你自己再去验证下吧,
我就不截图了.
验证的时候报了这个错误呢?
awk: line 2: illegal reference to array name
awk: line 3: illegal reference to array name
awk: line 4: illegal reference to array name
没看出什么问题呀。。
复制粘贴的时候注意换行符, 这里每行有字数限制, 会自动换行。
如果是用脚本, 保持截图中的格式
如果直接敲的命令, 第2条awk语句占一行, 不是多行.
cat file1 file2 | sort -k 1 | awk 'BEGIN{lk=""} lk==$1{printf(" %s",$2)} FNR!=1&&lk!=$1{printf("\n")} lk!=$1{printf("%s %s",$1,$2)} {lk=$1} '
说明:
lk记录上条记录的key,即第一列
lk==$1{printf(" %s",$2)} 负责add已存在的记录
FNR!=1&&lk!=$1{printf("\n")} 除第一条外,新添加的key需结束上条添加状态
lk!=$1{printf("%s %s",$1,$2)} 负责创建新key的记录
{lk=$1} 更新上条记录key值