免费注册 查看新帖 |

Chinaunix

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

如果替换匹配模式中的字符呢? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-09 22:18 |只看该作者 |倒序浏览
有文件如下:
a,b,c,d,e,f,g,h,i,j
20090608,正常,张三,0,0,"213421223498 ", ,0,119.20,119.20
20090608,正常,李 三,1,0,"8974385498  ",  ,"23,195.77",0,"23,195.77"
20090608,正常,李四,0,0,"117412385446  ",  ,195.77,0,"24,195.54"
20090608,正常,李 三,0,0,"8974385498  ",  ,12.55,0,775.12
...
...
希望将后引号中数字的千分位分隔符去掉,
得到如下结果:
a,b,c,d,e,f,g,h,i,j
20090608,正常,张三,0,0,"213421223498 ", ,0,119.20,119.20
20090608,正常,李 三,1,0,"8974385498  ",  ,"23195.77",0,"23195.77"
20090608,正常,李四,0,0,"117412385446  ",  ,195.77,0,"24195.54"
20090608,正常,李 三,0,0,"8974385498  ",  ,12.55,0,775.12
...
...

[ 本帖最后由 MicroHard 于 2009-6-9 22:53 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-06-09 22:49 |只看该作者
sed -e "s/[^.]\([1-9][0-9]*\),\([0-9]\{3\}\)/\1\2/g" a.txt

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
3 [报告]
发表于 2009-06-09 22:52 |只看该作者
try:
  1. awk -F \" -v OFS=\" '{for(i=1;i<=NF;i++) if(i%2==0)gsub(/,/,"",$i);print}' urfile
复制代码

论坛徽章:
0
4 [报告]
发表于 2009-06-09 23:07 |只看该作者
原帖由 ppshw 于 2009-6-9 22:49 发表
sed -e "s/[^.]\([1-9][0-9]*\),\([0-9]\{3\}\)/\1\2/g" a.txt

这个遇到文件中"10,122,076.86"这样的数字就出错了,得到错误的:10122,076.86"
blackold的没发现问题,不过好象运行有点慢。

[ 本帖最后由 MicroHard 于 2009-6-9 23:08 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-06-09 23:20 |只看该作者

  1. awk -v RS="\"" 'NR%2==0{gsub(",","")}{printf (NR==1?"":"\"")$0}' URFILE
复制代码

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
6 [报告]
发表于 2009-06-09 23:21 |只看该作者

回复 #4 MicroHard 的帖子

你的文件很大吗?

对于特定的文件:
  1. sed ':n;s/\("[0-9]\+\),\([0-9.,]*"\)/\1\2/;tn' urfile
复制代码

论坛徽章:
0
7 [报告]
发表于 2009-06-09 23:53 |只看该作者
$wc URFILE
45584  155232 5361840 URFILE
经过反复测试,结果还是blackold的awk最快,都差不多得到如下结果:
time awk -F \" -v OFS=\" '{for(i=1;i<=NF;i++) if(i%2==0)gsub(/,/,"",$i);print}' URFILE > bb
real    0m0.997s
user    0m0.951s
sys     0m0.045s


time awk -v RS="\"" 'NR%2==0{gsub(",","")}{printf (NR==1?"":"\"")$0}' URFILE > cc
real    0m1.125s
user    0m1.075s
sys     0m0.048s

time sed ':n;s/\("[0-9]\+\),\([0-9.,]*"\)/\1\2/;tn' URFILE > aa
real    0m3.039s
user    0m2.980s
sys     0m0.060s

论坛徽章:
0
8 [报告]
发表于 2009-06-10 00:35 |只看该作者
如果对1秒还不满意,那就写个C程序吧,我随便写了一个测试了一下,大概能比黑哥前面那个节省一半以上的时间。


  1. #include <stdlib.h>
  2. #include <stdio.h>

  3. int main()
  4. {
  5.     char c, t=0;
  6.     FILE *fp = fopen("URFILE","rb");
  7.     while (1)
  8.     {
  9.         c=fgetc(fp);
  10.         if(c==EOF) break;
  11.         switch (c)
  12.         {
  13.             case '"': t=1-t; putchar(c); break;
  14.             case ',': if(!t) putchar(c); break;
  15.             default : putchar(c); break;
  16.         }
  17.     }
  18.     fclose(fp);
  19.     return 0;
  20. }
复制代码

论坛徽章:
0
9 [报告]
发表于 2009-06-10 00:38 |只看该作者

  1. [root]# time ./mytr > /dev/null

  2. real    0m0.961s
  3. user    0m0.944s
  4. sys     0m0.017s

  5. [root]# time awk -F \" -v OFS=\" '{for(i=1;i<=NF;i++) if(i%2==0)gsub(/,/,"",$i);print}' tt > /dev/null

  6. real    0m3.308s
  7. user    0m3.281s
  8. sys     0m0.028s
复制代码

论坛徽章:
0
10 [报告]
发表于 2009-06-10 00:57 |只看该作者

回复 #8 kwokcn 的帖子

学习了,
t为啥设成char型?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP