免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
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
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-10-22 13:21 |只看该作者 |倒序浏览
请教一个perl的写法!谢谢!
将input.txt文件中的第2byte的值设定到第11byte,输出output.txt

处理对象文件内容
$cat input.txt
1F 123456 T qqqqq zzz              
2G 7测012 T qqqqq zzz
3V 1试456 T qqqqq zzz
4H 234567 T qqqqq zzz
90000000

想要的结果是
$cat output.txt
1F 123456 F qqqqq zzz            
2G 7测012 G qqqqq zzz
3V 1试456 V qqqqq zzz
4H 234567 H qqqqq zzz
90000000

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

有几点不太明白, 还请楼主解释一下:
1.> 主机环境是什么? (Linux | Windows)
2.> 您的文本中汉字占用几个字节? (1 | 2 | 3 | 4)

论坛徽章:
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
3 [报告]
发表于 2015-10-22 15:30 |只看该作者
sunzhiguolu 发表于 2015-10-22 15:20
有几点不太明白, 还请楼主解释一下:
1.> 主机环境是什么? (Linux | Windows)
2.> 您的文本中汉字占用几个 ...


你好!
1.主机环境是Linux
2.文本中汉字占用两个字节

论坛徽章:
0
4 [报告]
发表于 2015-10-22 15:32 |只看该作者



这样就可以搞定吧~~~

s/(.)(.)(........)(.)(.*)/$1$2$3$2$5/;

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

回复 3# robinhappiness
确定汉字在文本中占用两个字节? 您测试过了吗? (编码方式是什么)
能否将测试的结果贴出来?

   

论坛徽章:
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
6 [报告]
发表于 2015-10-22 16:26 |只看该作者
sunzhiguolu 发表于 2015-10-22 15:38
回复 3# robinhappiness
确定汉字在文本中占用两个字节? 您测试过了吗? (编码方式是什么)
能否将测试的结 ...


测试了一下您的sed命令,请教一个问题。

处理对象文件内容
$cat target.txt
1F 123456 T qqqqq zzz              
2G 7测012 T qqqqq zzz
3V 1试456 T qqqqq zzz
4H 234567 T qqqqq zzz
90000000

实际执行结果
1F 123456 F qqqqq zzz              
2G 7测012 TG qqqqq zzz
3V 1试456 TV qqqqq zzz
4H 234567 H qqqqq zzz
90000000


想要的结果是
1F 123456 F qqqqq zzz            
2G 7测012 G qqqqq zzz
3V 1试456 V qqqqq zzz
4H 234567 H qqqqq zzz


----------------
我是这样实现的。
cut原文件的第2列,aaa.txt
然后再cut原文件的1到10列,bbb.txt
然后再cut原文件的12列以后,ccc.txt

然后取消aaa.txt bbb.txt 换行之后合并cat bbb.txt aaa.txt ccc.txt > output.txt

感觉这个办法有点儿饶,所以想请教有没有更好的办法。

论坛徽章:
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
7 [报告]
发表于 2015-10-22 17:21 |只看该作者
处理汉字的问题我也比较菜鸟, 恐怕让您失望了.
只有请高手替您解答这个问题了, 我也想知道如何完美解决这个问题的方法. 帮顶!

论坛徽章:
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
8 [报告]
发表于 2015-10-22 22:12 |只看该作者
应为有 90000000 这种不需要替换的行,所以单纯的 substr 不行。

use bytes;  #他能保证匹配是按字节来的,无需考虑中文字符的问题。这里没必要加就是个保险
while (<>) {
    s/^(.(.) .{6} )./$1$2/; # 有两个空格,用来区分格式,避开 9000000 这样的行
    print $_;
}

论坛徽章:
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
9 [报告]
发表于 2015-10-22 22:37 |只看该作者
回复 1# robinhappiness


    直接按域处理么,数什么字节。

#!/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

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

回复 8# zhlong8
大神您好, 在 Linux 环境下如何确保中文字符按照 个字节进行处理.
测试环境:linux
测试文本:
1.> 编码方式: utf-8
2.> 使用桌面环境, 右键创建空文档的方式创建的测试文件 input.txt

本地语言环境:
  1. LANG=zh_CN.UTF-8
  2. LC_CTYPE="zh_CN.UTF-8"
  3. LC_NUMERIC="zh_CN.UTF-8"
  4. LC_TIME="zh_CN.UTF-8"
  5. LC_COLLATE="zh_CN.UTF-8"
  6. LC_MONETARY="zh_CN.UTF-8"
  7. LC_MESSAGES="zh_CN.UTF-8"
  8. LC_PAPER="zh_CN.UTF-8"
  9. LC_NAME="zh_CN.UTF-8"
  10. LC_ADDRESS="zh_CN.UTF-8"
  11. LC_TELEPHONE="zh_CN.UTF-8"
  12. LC_MEASUREMENT="zh_CN.UTF-8"
  13. LC_IDENTIFICATION="zh_CN.UTF-8"
  14. LC_ALL=
复制代码
测试代码如下: (只抓取前 10 个字符)

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use bytes;

  4. while (<>){
  5.    if (m{(.{10})}){
  6.        my $leng = length ($1);
  7.        printf "Length = %d, |%s|\n", $leng, $1;
  8.        my @a_10c = split //, $1;
  9.        foreach (@a_10c){
  10.           printf "<%s>=%d ", $_, length ($_);
  11.        }
  12.        print "\n";
  13.     }
  14. }
复制代码
输出结果如下:

  1. Length = 10, |1F 123456 |
  2. <1>=1 <F>=1 < >=1 <1>=1 <2>=1 <3>=1 <4>=1 <5>=1 <6>=1 < >=1
  3. Length = 10, |2G 7测012|
  4. <2>=1 <G>=1 < >=1 <7>=1 <?>=1 <?>=1 <?>=1 <0>=1 <1>=1 <2>=1
  5. Length = 10, |3V 1试456|
  6. <3>=1 <V>=1 < >=1 <1>=1 <?>=1 <?>=1 <?>=1 <4>=1 <5>=1 <6>=1
  7. Length = 10, |4H 234567 |
  8. <4>=1 <H>=1 < >=1 <2>=1 <3>=1 <4>=1 <5>=1 <6>=1 <7>=1 < >=1
复制代码
输出结果中连续的 3 个 ? (问号字符) 表示一个汉字字符, 每个汉字部分占用 3 个字节长度.

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP