在一个文件的两行之间复制代码,并在另一文件的相同两行之间覆盖

时间:2018-10-16 00:55:17

标签: python python-3.x

我正在尝试从一个文件的两个特定行之间复制代码,并将其粘贴到另一个文件的相同的两个对应行之间。

例如,我有两个文件test.sv_old和test.sv。我想在下面两行之间将代码从test.sv_old文件复制到test.sv

第1行:“ //此处是功能说明的开始”

第2行:” //如果没有电源,输出设置为0。根据需要取消注释。”

这是test.sv_old文件的内容:

`include "def.sv"
/PRIMARY  
/SECONDARY  
/TERTIARY  
/UNASSIGNED
module abc (  );
we want to see this too
//Start of functional specification here


//Functional cell instantiation 
abc_real Inst0  (.z1(int_z1), 
    .z2(int_z2), 
    .a1(reg_a1));

// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // abc
`include "def.sv"
/PRIMARY  
/SECONDARY  
/TERTIARY  
/UNASSIGNED
module xyz (  );
//Start of functional specification here


//Functional cell instantiation 
xyz_real Inst0  (.y1(int_y1), 
    .y2(int_y2), 
    .a1(reg_a1));

// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // xyz
`include "def.sv"
/PRIMARY  
/SECONDARY  
/TERTIARY  
/UNASSIGNED
module lmn (  );
//Start of functional specification here


//Functional cell instantiation 
lmn_real Inst0  (.x1(int_x1), 
    .x2(int_x2), 
    .a1(reg_a1));

// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // lmn

这是我的test.sv文件:

`include "def.sv"
//PRIMARY  
//SECONDARY  
//TERTIARY 
//UNASSIGNED 
module abc (  );
keep this code untouched
no change needed here
//Start of functional specification here


//Functional cell instantiation 
some garbage
here 
just replace this

// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // abc
`include "def.sv"
//PRIMARY  
//SECONDARY  
//TERTIARY  
//UNASSIGNED 
module xyz (  );
keep this as it is
input a1;
//Start of functional specification here


//Functional cell instantiation 
some garbage
here and there
why not just replace this


// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // xyz
`include "def.sv"
//PRIMARY  
//SECONDARY 
//TERTIARY 
//UNASSIGNED 
module lmn (  );
keep this as it is
input a1;
//Start of functional specification here


//Functional cell instantiation 
some garbage
here and there
why not just replace this


// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // lmn

我尝试了下面的代码,但没有给出我需要的确切输出:

import sys,re,os

rf_SVFile=open(sys.argv[1],"r")

wtstring = ""
wtindex = 0
copy = False
write = False
print("Copying instantiation code from {} to new SV file {}".format(rf_SVFile.name,sys.argv[2]))
for vline in rf_SVFile:
    if vline.strip() == "//Start of functional specification here" and copy == False:
        copy = True
    elif vline.strip() == "// Outputs set to 0 if no supply. Uncomment as needed.":
        copy = False
    elif copy:
        wtstring = wtstring + vline  # wtstring has the functional code between two lines which you want to write to .sv file

with open(sys.argv[2], "r+") as wf_NewSVFile:
    insert = False
    contents = wf_NewSVFile.readlines()
    for index, svline in enumerate(contents):
        if svline.strip() == "// Outputs set to 0 if no supply. Uncomment as needed.":
            wtindex = index
            insert = True
            break
    contents.insert(wtindex,wtstring)  # contents has complete code in list format, instantantiation code is copied from SV file to new SV File
    stringContents = "".join(contents)  # convert list into string in order to write it to .sv file
    if insert:
        wf_NewSVFile.seek(0, 0)
        wf_NewSVFile.write(str(stringContents))
    else:
        print(
            'Warning: No "/ Outputs set to 0 if no supply. Uncomment as needed." line found in {}, hence code is not being copied to new SV file',NewSVFile)

这是上面的代码生成的修改后的test.sv文件:

`include "def.sv"
//PRIMARY  
//SECONDARY  
//TERTIARY 
//UNASSIGNED 
module abc (  );
keep this code untouched
no change needed here
//Start of functional specification here


//Functional cell instantiation 
some garbage
here 
just replace this



//Functional cell instantiation 
abc_real Inst0  (.z1(int_z1), 
    .z2(int_z2), 
    .a1(reg_a1));



//Functional cell instantiation 
xyz_real Inst0  (.y1(int_y1), 
    .y2(int_y2), 
    .a1(reg_a1));



//Functional cell instantiation 
lmn_real Inst0  (.x1(int_x1), 
    .x2(int_x2), 
    .a1(reg_a1));

// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // abc
`include "def.sv"
//PRIMARY  
//SECONDARY  
//TERTIARY  
//UNASSIGNED 
module xyz (  );
keep this as it is
input a1;
//Start of functional specification here


//Functional cell instantiation 
some garbage
here and there
why not just replace this


// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // xyz
`include "def.sv"
//PRIMARY  
//SECONDARY 
//TERTIARY 
//UNASSIGNED 
module lmn (  );
keep this as it is
input a1;
//Start of functional specification here


//Functional cell instantiation 
some garbage
here and there
why not just replace this


// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // lmn

谁能解释,我在做什么错?谢谢。

3 个答案:

答案 0 :(得分:2)

使用一些关键字创建索引,然后加入切片应该可以解决问题。

with open('test.sv') as f:
    content = f.readlines()

with open('test_old.sv') as f:
    content_2 = f.readlines()

cp_s = [i for i, v in enumerate(content_2) if 'Functional' in v]
cp_end = [i for i, v in enumerate(content_2) if 'Outputs' in v]
dest_s = [i for i, v in enumerate(content) if 'Functional' in v]
dest_end = [i for i, v in enumerate(content) if 'Outputs' in v]

new = content[:dest_s[0]] + content_2[cp_s[0]: cp_end[0]] + content[dest_end[0]: dest_s[1]] +
content_2[cp_s[1]:]

with open('fixed.sv', 'w') as f:
    f.write(''.join(new))

输出:

chrx@chrx:~/python/stackoverflow/10.11$ cat fixed.sv 
module abc (  );
keep this code untouched
no change needed here
//Start of functional specification here


//Functional cell instantiation 
abc_real Inst0  (.z1(int_z1), 
    .z2(int_z2), 
    .a1(reg_a1));

// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // abc

module xyz (  );
keep this as it is
input a1;
//Start of functional specification here


//Functional cell instantiation 
xyz_real Inst0  (.z1(int_z1), 
    .z2(int_z2), 
    .a1(reg_a1));


// Outputs set to 0 if no supply. Uncomment as needed.
endmodule // xyz

答案 1 :(得分:1)

  

问题:有人可以解释我在做什么错吗?

您的代码离完成代码很远。
我会建议以下逻辑:

  1. 逐行读取test.sv_oldtest.sv文件
  2. 从每个moduleendmodulelistdict {<module name>:<module body>}个,
    符合以下条件:
    test.sv_old中,从//Functional读取,直至 //Output
    test.sv//Functional读取所有除外,并保留//Output作为占位符。
  3. //Functionallist的{​​{1}}
    1. dict逐行写入
    2. test.sv行从dict {<module name>:<module body>}切换到//Functional并写完整的dict
    3. 继续写test.sv_old中剩余的<module body>

答案 2 :(得分:1)

这似乎可以满足您的要求。即当我diff将您的所需的test.sv test_so79.new.txt 相等时。我留下了一些调试资料,您可能需要它;-)而正则表达式拆分来自In Python, how do I split a string and keep the separators?

import re
import pdb

def chunker_module(module_):

    # might need to make them more specific, but to lazy to regex-escape
    # all your stuff
    marker1 = "//Start.+$"
    marker2 = "//\sOutputs.+$"

    patre = re.compile("(%s|%s)" % (marker1, marker2), re.MULTILINE)

    res = patre.split(module_)
    try:
        assert len(res) == 5
    except (Exception,) as e:
        pdb.set_trace()
        raise

    head, tgt, tail = (res[0] + res[1], res[2], res[3] + res[4])

    return head, tgt, tail

def chunk_file(fnp):

    patre = re.compile("(module\s.+;$)", re.MULTILINE)

    with open(fnp) as fi:
        code = fi.read()

    splits_ = patre.split(code)


    modules = []

    #hmmm, wonder if the 1+2, 3, 4+5 approach would work here too...
    current = ""
    for item in splits_:
        if patre.search(item):
            modules.append(current)
            current = item
        else:
            current += item
    modules.append(current)

    # def debug_():
    #     for ix, mo in enumerate(modules):
    #         print("%s:\n%s" % (ix,mo))

    # debug_()
    # pdb.set_trace()

    # print(modules)
    return modules

modules_old = chunk_file("test_so79.old.txt")
modules_new = chunk_file("test_so79.txt")

lines_out = []

for mo, mn in zip(modules_old, modules_new):
    #actually, if mo/mn doesn't start with your //module marker
    #you might to append mn to lines_out -- it's from your new
    #file but doesnt need processing
    if not mo:
        continue

    _, keep, _ = chunker_module(mo)
    p1, _, p3 = chunker_module(mn)

    # def debug_():
    #     print(p1, keep, p3)
    # pdb.set_trace()
    # debug_()


    lines_out.extend([p1, keep, p3])

with open("test_so79.new.txt", "w") as fo:
    for line in lines_out:
        fo.write("%s\n" % (line))

要详细说明我对zip锁步约束的评论,如果旧模块的顺序是abc, xyz,而新模块的顺序是xyz,abc,那么您将不得不有所不同。

这应该使您入门:

di_old_module = dict([(module.name,module) for module in modules_old])
....
for mn in modules_new:
   mo = di_old_module[mn.name]
   _, keep, _ = chunker_module(mo)
   p1, _, p3 = chunker_module(mn)