忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12下一页
最近访问板块 发新帖
查看: 2352 | 回复: 11

[文本处理] linux下批量替换的问题 [复制链接]

论坛徽章:
0
发表于 2017-09-21 12:28 |显示全部楼层
有一个数据文件a:
# 990430_232320 000210_132231 0.0
YOS -0.22000003
YUL 0.079999924
# 990501_000720 000210_132231 0.0
LIJ -0.080000043
YUL 0.12 1 P
# 990707_214529 000210_132231 0.0
YOS 0.059999943
# 990907_090133 000210_132231 0.0
BAS 0.38 1 P
# 991027_211412 000210_132231 0.0
HEQ -0.65999997


其中#后的两列为ID(旧),此外还有一ID列表b,第一列为旧的ID,第二列为新的ID:
000210_132231 1001
990430_232320 1002
990501_000720 1003
990707_214529 1004
990907_090133 1005
991027_211412  1006
现在想把a中的所有旧ID替换成新的ID,生成文件c:
# 1002 1001 0.0
YOS -0.22000003
YUL 0.079999924
# 1003 1001 0.0
LIJ -0.080000043
YUL 0.12 1 P
# 1004 1001 0.0
YOS 0.059999943
# 1005 1001 0.0
BAS 0.38 1 P
# 1006 1001 0.0
HEQ -0.65999997


我之前用sed一个一个替换,但是由于数据太多,执行效率太低了,后来用awk的双文件处理,但是执行过程中会出错,命令如下:
awk 'NR==FNR{a[$1]=$2;next}NR>FNR{if($2 in a)print $1,a[$1],$3,$4;else print $0}' b a > temp
awk 'NR==FNR{a[$1]=$2;next}NR>FNR{if($3 in a)print $1,$2,a[$1],$4;else print $0}' b temp > c

请问是哪里出错了,应该怎样做,谢谢!

论坛徽章:
117
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07巳蛇
日期:2014-05-09 16:43:18巨蟹座
日期:2014-10-23 17:48:38子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59
发表于 2017-09-21 12:41 |显示全部楼层
回复 1# ilovefushun

$ awk 'FNR==NR{a[$1]=$2;next}/^#/{for(n=2;n<NF;++n)if($n in a)$n=a[$n]}1' b a > c

$ cat c
# 1002 1001 0.0
YOS -0.22000003
YUL 0.079999924
# 1003 1001 0.0
LIJ -0.080000043
YUL 0.12 1 P
# 1004 1001 0.0
YOS 0.059999943
# 1005 1001 0.0
BAS 0.38 1 P
# 1006 1001 0.0
HEQ -0.65999997

论坛徽章:
0
发表于 2017-09-21 13:06 |显示全部楼层
回复 2# jason680

可以了,谢谢!

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-09-21 13:21 |显示全部楼层
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my $keys = {};
  5. while(<DATA>){
  6.         last if(/\A\s*\z/);
  7.         my ($old, $new) = split;
  8.         $keys->{$old} = $new;
  9. }

  10. while(<DATA>){
  11.         if(!/\A#/){
  12.                 print;
  13.                 next;
  14.         }
  15.         foreach my $id (grep {exists($keys->{$_})} (split)[1, 2]){
  16.                 s/$id/$keys->{$id}/;
  17.         }
  18.         print;
  19. }

  20. __DATA__
  21. 000210_132231 1001
  22. 990430_232320 1002
  23. 990501_000720 1003
  24. 990707_214529 1004
  25. 990907_090133 1005
  26. 991027_211412  1006

  27. # 990430_232320 000210_132231 0.0
  28. YOS -0.22000003
  29. YUL 0.079999924
  30. # 990501_000720 000210_132231 0.0
  31. LIJ -0.080000043
  32. YUL 0.12 1 P
  33. # 990707_214529 000210_132231 0.0
  34. YOS 0.059999943
  35. # 990907_090133 000210_132231 0.0
  36. BAS 0.38 1 P
  37. # 991027_211412 000210_132231 0.0
  38. HEQ -0.65999997
复制代码

论坛徽章:
1
CU十四周年纪念徽章
日期:2017-08-28 17:16:19
发表于 2017-09-21 14:14 |显示全部楼层
本帖最后由 龙牙地主天 于 2017-09-21 14:23 编辑
  1. awk 'NR==FNR{a[$1]=$2 ; next}/^#/{for(i in a) {if($2==i) $2=a[$2] ; if($3==i) $3=a[$3]}}1' b a
复制代码

  1. awk 'NR==FNR{a[$1]=$2 ; next}/^#/{for(i in a) {if($2==i) $2=a[$2] ; if($3==i) $3=a[$3]}}{print > "c"}' b a
复制代码

论坛徽章:
2
程序设计版块每日发帖之星
日期:2016-05-03 06:20:0015-16赛季CBA联赛之同曦
日期:2017-09-11 14:39:48
发表于 2017-09-21 14:17 |显示全部楼层
本帖最后由 wh7211 于 2017-09-21 14:22 编辑

回复 1# ilovefushun


  1. awk 'NR==FNR{a[$1]=$2;next}/^#/{$2=$2 in a?a[$2]:$2;$3=$3 in a?a[$3]:$3}{print>"c"}' b a
复制代码

论坛徽章:
0
发表于 2017-09-21 15:10 |显示全部楼层
a b 文件都多大?
你这是查找替换哈希表的问题。
powershell 把a文件,或者一部分,放在大内存对象中,就比较快。
否则1行行弄就比较慢。
典型的空间换时间的问题。

论坛徽章:
0
发表于 2017-09-21 15:49 |显示全部楼层
本帖最后由 ilovefushun 于 2017-09-21 16:00 编辑

回复 2# jason680

不好意思,还有一个问题。if($2 in a),表示如果$2的值在数组a中,则执行后面的命令,我想问一下如果$2的值不在数组a中应该怎么写?if(! $2 in a),if !($2 in a),!(if($2 in a)),这几种写法都试了,但是都运行不了

论坛徽章:
117
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07巳蛇
日期:2014-05-09 16:43:18巨蟹座
日期:2014-10-23 17:48:38子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59
发表于 2017-09-21 16:02 |显示全部楼层
本帖最后由 jason680 于 2017-09-21 16:05 编辑

回复 8# ilovefushun

$ echo 1 2 3 4 x y z| awk 'BEGIN{a[1]=a[4]=a["y"]=1}{for(n=1;n<=NF;++n)if($n in a)print $n}'
1
4
y

$ echo 1 2 3 4 x y z| awk 'BEGIN{a[1]=a[4]=a["y"]=1}{for(n=1;n<=NF;++n)if(!($n in a))print $n}'
2
3
x
z

$ echo 1 2 3 4 x y z| awk 'BEGIN{a[1]=a[4]=a["y"]=1}{for(n=1;n<=NF;++n)if($n in a)print "yes:"$n;else print "no:"$n}'
yes:1
no:2
no:3
yes:4
no:x
yes:y
no:z

论坛徽章:
0
发表于 2017-09-21 16:04 |显示全部楼层
回复 9# jason680

哦,知道了,谢谢您!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10张SACC2017门票等你来拿~

在数字化转型时代,云已成为万物智能的数字化大脑。而随着大数据应用、人工智能、移动互联网等技术的飞速发展,“智慧 +” 的概念正在深入到各行各业,提升企业效率,释放商业潜能,创造全新机遇。作为国内顶级技术盛会之一,2017 中国系统架构师大会(SACC2017)将于 10 月 19-21 日在北京新云南皇冠假日酒店震撼来袭。今年,大会以 “云智未来” 为主题,云集国内外顶级专家,围绕云计算、人工智能、大数据、移动互联网、产业应用等热点领域展开技术探讨与交流。本届大会共设置 2 大主会场,18 个技术专场;邀请来自互联网、金融、制造业、电商等多个领域,100 余位技术专家及行业领袖来分享他们的经验;并将吸引 4000 + 人次的系统运维、架构师及 IT 决策人士参会,为他们提供最具价值的交流平台。
----------------------------------------
优惠时间:2017年10月19日前

活动链接>>
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP