免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: robinhappiness
打印 上一主题 下一主题

请教一个替换文本文件中指定位置的值的perl的写法! [复制链接]

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
11 [报告]
发表于 2015-10-23 09:13 |只看该作者
回复 10# sunzhiguolu


    你最好按9楼写的那样换种思路,utf8 中文常用字都是3个字节的,但是后来陆续添加了不少生僻字长度就没法保证了。你还要把他们转换成两字节的,明显误入歧途了

论坛徽章:
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
12 [报告]
发表于 2015-10-23 09:18 |只看该作者
回复 11# zhlong8
谢谢您的提醒, 在 Windows 环境的确是按照每个汉字占用 2 字节进行处理的. 非常感谢您的帮助, 谢谢...

   

论坛徽章:
4
程序设计版块每日发帖之星
日期:2015-10-10 06:20:00每日论坛发贴之星
日期:2015-10-10 06:20:00程序设计版块每日发帖之星
日期:2015-10-11 06:20:00程序设计版块每日发帖之星
日期:2015-10-25 06:20:00
13 [报告]
发表于 2015-10-23 09:29 |只看该作者
非常感谢各位高人的回复!

我之前做的测试数据比较规范,实际上要处理的对象文件里面包含有全角和半角的空格、汉字、数字、符号等都有,
而且每个字段的划分也没规律,打个比方我要把第2byte的数值插入到第25byte的位置(zz0和yyy之间),
第1和第2byte位置的值肯定只占一个字节,还有第25byte的位置肯定为只站一个字节的半角空格。
字段的布局没有规律!

想要做的事情就是把文件中的第2byte位置的列值(只占1个字节的字母)
赋值到文件中第25byte空格(只占一个字节的半角空格)的位置。

对象文件
$cat input.txt
1000000
1F 123456 ー  qqq q zz0 yyy  
2G 7测012 --  q qq  zz0 yyy
3V 1试456     qq  qq zz0 yyy
4H 234567    qqq  q zz0 yyy
09000000

想要的输出结果
$cat output.txt
1000000
1F 123456 ー  qqq q zz0Fyyy  
2G 7测012 --  q qq  zz0Gyyy
3V 1试456     qq  qq zz0Vyyy
4H 234567    qqq  q zz0Hyyy
09000000

论坛徽章:
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
14 [报告]
发表于 2015-10-23 09:38 |只看该作者
本帖最后由 sunzhiguolu 于 2015-10-23 09:39 编辑

回复 9# MMMIX
#!/usr/bin/perl
use strict;
use warnings;
use v5.14;

while (<DATA>) {
  chomp;
  my @f = split;
  say and next unless @f > 1;

  $f[2] = (split //, $f[0])[1];
  say join " ", @f;
}

__DATA__
1F 123456 T qqqqq zzz
2G 7测012 T qqqqq zzz
3V 1试456 T qqqqq zzz
4H 234567 T qqqqq zzz
90000000

请问大神, and 在 say 函数和 next unless @f > 1 语句块之间起到一个什么作用? (不知道划分的是否正确?)


   

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
15 [报告]
发表于 2015-10-23 20:35 |只看该作者
回复 14# sunzhiguolu


    say and next unless @f > 1;

等价于

   if (@f > 1) {
       say;
       next;
   }

第二种写法更好。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
16 [报告]
发表于 2015-10-23 20:49 |只看该作者
回复 13# robinhappiness


    这个就更简单了,用 split + join 就可以了:

while (<DATA>) {
  my @f = split //;
  $f[24] = $f[1] if @f > 24;
  print join '', @f;
}

论坛徽章:
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
17 [报告]
发表于 2015-10-23 20:51 |只看该作者
本帖最后由 sunzhiguolu 于 2015-10-23 20:54 编辑

回复 15# MMMIX
say and next unless @f > 1;

大神, 您这句不是针对 90000...行 写的判断条件吗?
如果上面的这个语句与您下面的这句等价, 那么最后一行不就多余了吗?
if (@f > 1){
   say;
   next;
}
   

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
18 [报告]
发表于 2015-10-23 21:02 |只看该作者
回复 17# sunzhiguolu


    把我改写的替换进去,然后再按你的理解把觉得多余的语句删除看看效果。

论坛徽章:
4
程序设计版块每日发帖之星
日期:2015-10-10 06:20:00每日论坛发贴之星
日期:2015-10-10 06:20:00程序设计版块每日发帖之星
日期:2015-10-11 06:20:00程序设计版块每日发帖之星
日期:2015-10-25 06:20:00
19 [报告]
发表于 2015-10-25 21:53 |只看该作者
MMMIX 发表于 2015-10-23 20:49
回复 13# robinhappiness


我上传一个input文件和一个output文件图片来说明一下。
文件内容中,每条记录的长度都占50byte,在每行的第51byte位置开始换行。
除了第一行和最后一行之外的第2byte位置的值需要设定到第25byte位置。
处理前后的文件大小不能够有差异。文件中含有半角,全角的字符,数字,空格等。

input.txt:

1sadw2we21                                       
1F 123456  ー-  qqq  00      00000000            
2G 7漢012 -  -  qq  00      00000000            
3V 1字456   /  q q  00      00000000            
4H 234567 1 2 3  q 00      00000000            
0900000000                                       


output.txt:

1sadw2we21                                       
1F 123456  ー-  qqq  00F     00000000            
2G 7漢012 -  -  qq  00G     00000000            
3V 1字456   /  q q  00V     00000000            
4H 234567 1 2 3  q 00H     00000000            
0900000000                                       

论坛徽章:
0
20 [报告]
发表于 2015-10-26 17:32 |只看该作者
本帖最后由 xie3ks 于 2015-10-26 17:35 编辑
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;

  4. while(<DATA>)
  5. {
  6.     my @bytes_value=split //;

  7.     $bytes_value[10]=$bytes_value[1] if defined $bytes_value[10];
  8.     print join "",@bytes_value;
  9. }

  10. __DATA__
  11. 1F 123456  T qqqqq zzz              
  12. 2G 7测012 T qqqqq zzz
  13. 3V 1试456 T qqqqq zzz
  14. 4H 234567 T qqqqq zzz
  15. 90000000
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP