免费注册 查看新帖 |

Chinaunix

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

[文本处理] 比较并打印两个定长文本各个字段的差异 [复制链接]

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
11 [报告]
发表于 2015-06-21 16:23 |只看该作者

  1. cat file1
  2. A           1         4
  3. B           5         2
  4. C           7         3
  5. D           10       2
  6. cat file2
  7. 2015GZ200a1
  8. cat file3
  9. 2015SZ200b1

  10. awk 'BEGIN{"cat file2"|getline var1;"cat file3"|getline var2}NR==FNR{print $1" <["substr(var1,$2,$3)"] >["substr(var2,$2,$3)"]"}' file1
  11. A <[2015] >[2015]
  12. B <[GZ] >[SZ]
  13. C <[200] >[200]
  14. D <[a1] >[b1]
复制代码

论坛徽章:
0
12
发表于 2015-06-22 00:00
回复 8# yestreenstars
大哥,之前的方法可以实现我的需求,谢谢了;现在需求升级了一下,有时间帮忙看下不


   

论坛徽章:
0
13
发表于 2015-06-22 00:01
回复 9# zxy877298415
大哥,之前的方法可以实现我的需求,谢谢了;现在需求升级了一下,有时间帮忙看下不

   

论坛徽章:
0
14 [报告]
发表于 2015-06-22 00:02 |只看该作者
回复 10# songyc_2015
大哥,之前的方法可以实现我的需求,谢谢了;现在需求升级了一下,有时间帮忙看下不

   

论坛徽章:
0
15 [报告]
发表于 2015-06-22 00:03 |只看该作者
回复 11# 聆雨淋夜
大哥,之前的方法可以实现我的需求,谢谢了;现在需求升级了一下,有时间帮忙看下不

   

论坛徽章:
20
卯兔
日期:2015-01-26 22:05:142015亚冠之萨济拖拉机
日期:2015-09-10 15:15:282015亚冠之阿尔希拉尔
日期:2015-09-25 17:37:53程序设计版块每日发帖之星
日期:2015-10-03 06:20:00程序设计版块每日发帖之星
日期:2015-12-09 06:20:00CU十四周年纪念徽章
日期:2015-12-17 09:07:15程序设计版块每日发帖之星
日期:2015-12-25 06:20:34程序设计版块每日发帖之星
日期:2015-12-25 06:20:34程序设计版块每日发帖之星
日期:2015-12-25 06:20:342015亚冠之广州富力
日期:2015-08-27 19:29:56每日论坛发贴之星
日期:2015-08-26 06:20:002015亚冠之阿尔希拉尔
日期:2015-05-18 17:26:27
16 [报告]
发表于 2015-06-22 01:08 |只看该作者
回复 1# Feyiz
  1. awk 'ARGIND==1{
  2.     if($1~/^第/)
  3.     {
  4.         j=0;
  5.         a[++i,j]=substr($1,1,3);
  6.         next
  7.     }
  8.     a[i,++j]=$1;
  9.     b[i]=length(b[i])?b[i]" "$NF:$NF;
  10.     next
  11. }
  12. {
  13.     FIELDWIDTHS=b[FNR];
  14.     $0=$0;
  15. }
  16. ARGIND==2{
  17.     for(i=1;i<=NF;i++)
  18.         c[FNR,i]=$i
  19. }
  20. ARGIND==3{
  21.     for(i=1;i<=NF;i++)
  22.     {
  23.         if (c[FNR,i] != $i)
  24.         {
  25.             printf("%s\t%s\t<[%s]\t>[%s]\n",a[FNR,0],a[FNR,i], c[FNR,i], $i);
  26.         }
  27.     }
  28. }
  29. ' 1 2 3
  30. 第一组  B       <[GZ200 ]       >[SZ0200]
  31. 第二组  C       <[201506]       >[201505]
  32. 第三组  H       <[4123c]        >[1   c]
复制代码

论坛徽章:
26
2015亚冠之胡齐斯坦钢铁
日期:2015-06-25 21:40:202015亚冠之柏斯波利斯
日期:2015-08-31 17:03:192015亚冠之柏斯波利斯
日期:2015-11-07 13:10:00程序设计版块每日发帖之星
日期:2015-11-10 06:20:00每日论坛发贴之星
日期:2015-11-10 06:20:00程序设计版块每日发帖之星
日期:2015-11-26 06:20:00程序设计版块每日发帖之星
日期:2015-12-02 06:20:00黄金圣斗士
日期:2015-12-07 17:57:4615-16赛季CBA联赛之天津
日期:2015-12-23 18:34:14程序设计版块每日发帖之星
日期:2016-01-02 06:20:00程序设计版块每日发帖之星
日期:2016-01-06 06:20:00每日论坛发贴之星
日期:2016-01-06 06:20:00
17 [报告]
发表于 2015-06-22 11:00 |只看该作者
文件file1file2file3的内容如下:
  1. file1:

  2. 第一组变量名   起始位置   长度
  3. A                   1         4
  4. B                   5         6
  5. 第二组变量名   起始位置   长度
  6. C                   1         6
  7. D                   7         2
  8. E                   6         1
  9. F                   7         6
  10. 第三组变量名   起始位置   长度
  11. G                   1        2
  12. H                   3        5

  13. file2:

  14. 2015GZ200 a1
  15. 201506GZA1
  16. 114123cc66

  17. file3:

  18. 2015SZ0200a1
  19. 201505GZA1
  20. 111   cc66
复制代码
输出结果
  1. 第一组        B        <[GZ200 ]        >[SZ0200]
  2. 第二组        C        <[201506]        >[201505]
  3. 第二组        E        <[6]        >[5]
  4. 第三组        H        <[4123c]        >[1   c]
复制代码
方法
python2 f123.py  file1 file2 file3
代码
  1. #!/usr/bin/python2
  2. # coding: utf-8
  3. # python2 f123.py  file1 file2 file3

  4. import sys
  5. FILES = [open(f) for f in sys.argv[1:]]
  6. group, file2, file3 = '', '', ''

  7. for line in FILES[0]:
  8.     if line.startswith('第'):
  9.         end   = line.index('变')
  10.         group = line[:end]
  11.         file2, file3 = [x.next() for x in FILES[1:]]
  12.         continue

  13.     ELEMENTS   = line.split()
  14.     START, LEN = [int(i) for i in ELEMENTS[1:]]
  15.     SUB2, SUB3 = [l[START - 1:START + LEN - 1] for l in [file2, file3]]

  16.     if SUB2 != SUB3:
  17.         print "%s\t%s\t<[%s]\t>[%s]" % (group, ELEMENTS[0], SUB2, SUB3)

  18. for f in FILES:
  19.     f.close()
复制代码

论坛徽章:
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
18 [报告]
发表于 2015-06-23 07:03 |只看该作者
回复 1# Feyiz

第一问 牙膏挤不完...

$ bash diff.sh
第一组 B  <[GZ200 ]            >[SZ0200]            st=5,len=6
第二组 C  <[201506]            >[201505]            st=1,len=6
第二组 E  <[6]                 >[5]                 st=6,len=1
第三组 H  <[4123c]             >[1   c]             st=3,len=5

$ cat check.txt
第一组变量名   起始位置   长度
   A                   1         4
   B                   5         6
第二组变量名   起始位置   长度
   C                   1         6
   D                   7         2
   E                   6         1
   F                   7         6
第三组变量名   起始位置   长度
   G                   1        2
   H                   3        5

$ bash diff.sh
第一组 B  <[GZ200 ]            >[SZ0200]            st=5,len=6
第二组 C  <[201506]            >[201505]            st=1,len=6
第二组 E  <[6]                 >[5]                 st=6,len=1
第三组 H  <[4123c]             >[1   c]             st=3,len=5
jason@jason-VirtualBox:~
$ cat diff.sh
awk '
function get(file, data){
  getline data < file;
  return data;
}
match($0,/(第..)/,m){
  a=get("a.txt");
  b=get("b.txt");
  item = m[1];
  next;
}
{   
    as=substr(a, $2, $3);
    bs=substr(b, $2, $3);
    if(as != bs){
      printf("%s %c  %-20s %-20s st=%d,len=%d\n",
           item, $1, "<["as"]", ">["bs"]",    $2,    $3 );
    }
}' check.txt

   

论坛徽章:
0
19 [报告]
发表于 2015-06-23 22:33 |只看该作者
本帖最后由 Feyiz 于 2015-06-23 22:49 编辑

首先,感谢:songyc_2015、substr函数、jason680 三位;你们精简的脚本让我学到了很多东西。
songyc_2015兄的这几句,个人感觉很妙,佩服
    if($1~/^第/)
{
        j=0;
        a[++i,j]=substr($1,1,3);
        next
    }
    a[i,++j]=$1;
    b=length(b)?b" "$NFNF;
    next
}
-------------------------------------------------------
substr函数兄的python脚本想必也有其精妙所在,可惜本人暂时对python不太懂,只能拿来用
-------------------------------------------------------
jason680兄的自定义函数实在是高,以前只知道awk有自定义函数功能,但是一直不知道怎么使用

其次,对于jason680兄说的 “第一问 牙膏挤不完...”;我是想学习一下你们从简单到复杂考虑问题的思路;一下把“牙膏挤完”,我怕自己看不懂跟不上你们的思路。其实这个需求还有一个终极版,本人想先结合你们给出的脚本与思路己学习尝试下自己能否搞定,再次感谢给位
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP