简体   繁体   English

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

[英]Copy code between two lines from one file and overwrite between same two lines in another file

I am trying to copy codes between two specific lines from one file and paste it between same two corresponding lines in another file. 我试图从一个文件中复制两个特定行之间的代码,并将其粘贴到另一个文件中相同的两个相应行之间。

For example I have two files test.sv_old and test.sv. 例如,我有两个文件test.sv_old和test.sv. I want to copy code from test.sv_old file to test.sv between below two lines 我想将test.sv_old文件中的代码复制到下面两行之间的test.sv

Line 1:"//Start of functional specification here" 第1行:“//这里开始功能规范”

Line2:"// Outputs set to 0 if no supply. Uncomment as needed." 第2行:“//如果没有供应,则输出设置为0。根据需要取消注释。”

Here is the content of test.sv_old file: 以下是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

Here is my test.sv file: 这是我的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

I have tried below code but it doesn't give me exact output I need: 我试过下面的代码,但它没有给我我需要的确切输出:

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)

and here is the modified test.sv file generated by above code: 这是由上面的代码生成的修改后的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

Can anyone explain, what I am doing wrong? 谁能解释一下,我做错了什么? Thanks. 谢谢。

Using some keywords to create indexes and then joining the slices should do the trick. 使用一些关键字来创建索引然后加入切片应该可以解决问题。

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))

Output: 输出:

 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 

Question : Can anyone explain, what I am doing wrong? 问题 :谁能解释一下,我做错了什么?

Your code is far away from Complete. 您的代码远离Complete。
I would recommend the following logic: 我会推荐以下逻辑:

  1. Read test.sv_old and test.sv files line by line test.sv_old读取test.sv_oldtest.sv文件
  2. From every module up to endmodule make a list of dict {<module name>:<module body>} 从每一个module最多endmodule使listdict {<module name>:<module body>}
    With these Conditions: 有了这些条件:
    From test.sv_old read only from //Functional up to //Output test.sv_old只读 //Functional最多//Output
    From test.sv read all except from //Functional up to //Output , keeping //Functional as a placeholder. test.sv读取 //Functional//Output 之外的所有内容,保持//Functional作为占位符。
  3. Loop the list of dict from test.sv test.sv循环dict list
    1. Write from dict {<module name>:<module body>} line by line 逐行写入dict {<module name>:<module body>}
    2. At the line //Functional switch to dict from test.sv_old and write the whole <module body> //Functional行的//Functional切换到test.sv_old dict并写入整个<module body>
    3. Continue writing remaining <module body> from test.sv 继续从test.sv写入剩余的<module body>

This seems to do what you wanted. 这似乎做你想要的。 ie when I diff your desired test.sv to test_so79.new.txt they're equal. 即当我将你想要的test.sv diff 化为 test_so79.new.txt时,他们是平等的。 I left some debug stuff, you might need it ;-) And the regex splitting came from In Python, how do I split a string and keep the separators? 我留下了一些调试内容,你可能需要它;-)并且正则表达式拆分来自In Python,如何拆分字符串并保留分隔符?

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))

To elaborate on my remark about the zip lockstep constraints, if old's module sequence was abc, xyz , and new's was xyz,abc , then you would have to treat things a little differently. 为了详细阐述我对zip锁步约束的评论,如果旧的模块序列是abc, xyz和new是xyz,abc ,那么你必须对待事情有点不同。

This should get you started: 这应该让你开始:

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)       

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM