【问题标题】:how to manipulate SREC file如何操作 SREC 文件
【发布时间】:2014-06-08 19:43:33
【问题描述】:

我有一个如下所示的 S19 文件:

S0030000FC
S30D0003C0000F0000000000000020
S3FD00000000782EFF1FB58E00003D2B00003D2B00003D2B00003D2B00003D2B00003D
S3ED000000F83D2B00003D2B00003D2B00003D2B00003D2B00003D2B00003D2B00003D
S31500000400FFFFFFFFFFFFFFFFFFFFFFFF7EF9FFFF7D
S3FD0000041010B5DFF828000468012147F22C10C4F20300016047F22010C4F2030000
S70500008EB4B8

我想将前两个字符和接下来的两个字符分开,依此类推...我希望它如下所示(每行的最后两个字符也将分开):

S0, 03, 0000, FC
S3, 0D, 0003C000, 0F00000000000000, 20
S3, FD, 00000000, 782EFF1FB58E00003D2B00003D2B00003D2B00003D2B00003D2B0000, 3D
S3, ED, 000000F8, 3D2B00003D2B00003D2B00003D2B00003D2B00003D2B00003D2B0000, 3D
S3, 15, 00000400, FFFFFFFFFFFFFFFFFFFFFFFF7EF9FFFF, 7D
S3, FD, 00000410, 10B5DFF828000468012147F22C10C4F20300016047F22010C4F20300, 00
S7, 05, 00008EB4, B8

如何在 Python 中做到这一点? 我有这样的事情:

 #!/usr/bin/python
 import string,os,sys,re,fileinput
 print "hi"
 inputfile = "k60.S19"
 outputfile = "k60_out.S19"

 # open the source file and read it
 fh = file(inputfile, 'r')
 subject = fh.read()
 fh.close()

 # create the pattern object. Note the "r". In case you're unfamiliar with Python
 # this is to set the string as raw so we don't have to escape our escape characters

 pattern2 = re.compile(r'S3')
 pattern3 = re.compile(r'S7')
 pattern1 = re.compile(r'S0')
 # do the replace
 result1 = pattern1.sub("S0, ", subject)
 result2 = pattern2.sub("S3, ", subject)
 result3 = pattern3.sub("S7, ", subject)

 # write the file
 f_out = file(outputfile, 'w')

 f_out.write(result1)
 f_out.write(result2)
 f_out.write(result3)
 f_out.close()

 #EoF

但它没有像我喜欢的那样工作!!有人可以帮我想出正确的正则表达式吗?

【问题讨论】:

  • 第一行呢:S0030000FC
  • 看起来可能需要将近一整行awk...
  • 我认为你不需要正则表达式,你需要切片...stackoverflow.com/questions/663171/…
  • @CasimiretHippolyte,是的,对不起,我错过了,我添加了。
  • @MarkSetchell,我必须尝试切片你建议...

标签: python regex substring string-matching


【解决方案1】:

尝试打包 bincopy,也许你需要它。

bincopy - 将字符串解释为打包的二进制数据

对传递二进制信息的各种文件格式(摩托罗拉 S-Record、英特尔 HEX 和二进制文件)进行处理。

import bincopy
f = bincopy.BinFile()
f.add_srec_file("path/to/your/s19/flie.s19")
f.as_binary() # print s19 as binary

或者您可以轻松地对文件使用 open():

with open("path/to/your/s19/flie.s19") as s19:
    for line in s19:
        type = line[0:2]
        count = line[2:4]
        adress = line[4:12]
        data = line[12:-2]
        crc = line[-2:]
        print type + ", "+ count + ", " + adress + ", " + data + ", " + crc + "\n"

希望对您有所帮助。 Motorola S-record file format

【讨论】:

    【解决方案2】:

    您可以使用回调函数替换re.sub

    #!/usr/bin/python
    import re
    
    data = r'''S0030000FC
    S30D0003C0000F0000000000000020
    S3FD00000000782EFF1FB58E00003D2B00003D2B00003D2B00003D2B00003D2B00003D
    S3ED000000F83D2B00003D2B00003D2B00003D2B00003D2B00003D2B00003D2B00003D
    S31500000400FFFFFFFFFFFFFFFFFFFFFFFF7EF9FFFF7D
    S3FD0000041010B5DFF828000468012147F22C10C4F20300016047F22010C4F2030000
    S70500008EB4B8'''
    
    pattern = re.compile(r'^(..)(..)((?:.{4}){1,2})(.*)(?=..)', re.M)
    
    def repl(m):
        repstr = ''
        for g in m.groups():
            if (g):
                repstr += g + ', '
        return repstr
    
    print re.sub(pattern, repl, data)
    

    但是,正如 Mark Setchell 所注意到的,切片可能是一种不错的方法。

    【讨论】:

      【解决方案3】:

      我知道您正在考虑 Python 和正则表达式,但这是为 awk 制作的,以下内容可能会帮助您找到使用切片的方法:

      awk '{r=length($0);print substr($0,1,2),substr($0,3,2),substr($0,5,8),substr($0,13,r-14),substr($0,r-1)}' OFS=, k60.s19
      

      这就是说“在变量r中获取行的长度,然后打印前两个字符,接下来的两个字符,接下来的8个字符等等......并使用逗号作为字段分隔符"。

      已编辑

      这里还有一些提示可以帮助您入门...

      如果你想避免打印第 1 行,你可以这样做

      awk 'FNR==1{next}  ...rest of awk script above ... ' 
      

      如果你只想处理超过 40 个字符的行,你可以这样做

      awk 'length($0)>40 {print}' yourfile
      

      如果你只想处理第二个字段为“xx”的行,你可以这样做

      awk '$2 ~ "xx" {print}' yourfile
      

      【讨论】:

      • 感谢@Mark,那个 substr($0,13,r-14) 是干什么用的?我认为 substr($0,r-1) 意味着取行尾+2个字符?
      • 没错。 13 表示从行首开始的第 13 个字符,r-14 表示取 r-14 个字符以允许前 2 个、间隙、下一个 2 和 8 个字符的块。
      • awk 是一个强大的命令!如果您想进行替换或表达式匹配删除怎么办,awk 可以与 sed 一起使用吗?我想我必须管这两个?例如,如果我想去掉第一行和最后一行,并且中间的字符串匹配'FD'?
      • 我为您的回答添加了一些额外的提示和技巧。希望对您有所帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 2015-12-11
      • 2014-09-09
      相关资源
      最近更新 更多