免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3729 | 回复: 11
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(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

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

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期: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未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
2 [报告]
发表于 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
3 [报告]
发表于 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
4 [报告]
发表于 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
复制代码

论坛徽章:
8
CU十四周年纪念徽章
日期:2017-08-28 17:16:1915-16赛季CBA联赛之北控
日期:2018-03-29 11:39:0615-16赛季CBA联赛之上海
日期:2018-05-21 10:46:10技术图书徽章
日期:2018-09-03 13:54:18技术图书徽章
日期:2018-09-03 13:54:2815-16赛季CBA联赛之四川
日期:2020-10-15 09:21:4720周年集字徽章-20	
日期:2020-10-28 13:53:0220周年集字徽章-庆
日期:2020-10-28 14:09:12
5 [报告]
发表于 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
复制代码

论坛徽章:
25
程序设计版块每日发帖之星
日期:2016-05-03 06:20:0015-16赛季CBA联赛之八一
日期:2018-07-05 10:34:09黑曼巴
日期:2018-07-06 15:19:5015-16赛季CBA联赛之佛山
日期:2018-08-03 13:19:3315-16赛季CBA联赛之山西
日期:2018-08-07 19:46:2315-16赛季CBA联赛之广夏
日期:2018-08-08 19:31:5015-16赛季CBA联赛之青岛
日期:2018-11-26 15:21:5015-16赛季CBA联赛之上海
日期:2018-12-11 09:45:3219周年集字徽章-年
日期:2020-04-18 23:54:5215-16赛季CBA联赛之深圳
日期:2020-04-19 21:40:19黑曼巴
日期:2022-04-03 17:55:1315-16赛季CBA联赛之八一
日期:2018-07-03 16:56:46
6 [报告]
发表于 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
7 [报告]
发表于 2017-09-21 15:10 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
8 [报告]
发表于 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)),这几种写法都试了,但是都运行不了

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期: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未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
9 [报告]
发表于 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
10 [报告]
发表于 2017-09-21 16:04 |只看该作者
回复 9# jason680

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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP