In the past days I had to build a script to insert some lines of code after a specific statement.
For example, I have the following file:
a > bAnd I need to add a line
a = foo(c)
b = 2
b = foo(b)
foo
bar
foobar
b = foo(v)
variable = bar(42)
after every line of variable = foo(x)
a > bAlso, I had to perform this task on multiple files at the same time, the files are listed in a visual studio search result that will look like this:
a = foo(c)
a = bar(42)
b = 2
b = foo(b)
b = bar(42)
foo
bar
foobar
c = foo(v)
c = bar(42)
Find all "foo(", Subfolders, Find Results 1, "c:\", "*.txt"So we need a way to get the set of files from the visual studio search result and then run the task on each of them.
C:\file1.txt(2):a = foo(c)
C:\file1.txt(4):b = foo(b)
C:\file1.txt(8):c = foo(v)
C:\file2.txt(2):a1 = foo(c)
C:\file2.txt(4):a3 = foo(b)
C:\file2.txt(8):variable1 = foo(v)
Matching lines: 6 Matching files: 2 Total files searched: 214
Find was stopped in progress.
LINE_TO_INSERT
is the line to insert, in this case = bar(42)\n
PATTERN_OF_LINE
in the pattern after which we insert the line'\w+' + '\\ \\=\\ foo\\(' + '\w+'
which matches with a = foo(b)
for examplePATTERN_OF_FILE
is the pattern of the files we are looking for in the visual studio search resultinsert_in_files()
.
def insert_in_files():
'''Insert LINE_TO_INSERT after all lines with pattern PATTERN_OF_LINE in all files with PATTERN_OF_FILE'''
files = get_files('vs_search_output.txt')
for f in files:
insert_lines(f)
return None
PATTERN_OF_FILE
is equal to 'C\\:\\\\\w+.txt'
. Which means any files with extension .txt
whose name is any word character.
def get_files(path):If you run this function you will get a set of files.
'''Return a set of files from a visual studio search output following a regexp pattern
Format of visual studio search output is the following:
Find all "pattern to search", Subfolders, Find Results 1, Entire Solution, "" path_to_file.txt(1): line with text path_to_another_file.txt(22): line1 some text path_to_another_file.txt(29): line2 some text Matching lines: 2 Matching files: 2 Total files searched: 205
Args:
path: A path to a file with the search result
Returns:
A set of all files in search result that match PATTERN_OF_FILE regular expression.
'''
from re import search
from re import escape
f = open(path, 'r')
# paths is a set structure with all the different files to look for.
paths = set()
count = 0
for line in f:
m = search(PATTERN_OF_FILE, line)
if m:
paths.add(m.group(0))
f.close()
return paths
insert_in_files
is the python file where the get_files
is located.vs_search_output.txt
is the visual studio search result listed above.>>> import insert_in_files
>>> insert_in_files.get_files("vs_search_output.txt")
{'C:\\file1.txt', 'C:\\file2.txt'}
>>>
PATTERN_OF_FILE = 'C\\:\\\\\w+.txt'And here is the code to search in a file and insert a line:
PATTERN_OF_LINE = '\w+' + '\\ \\=\\ foo\\(' + '\w+' # looking for pattern a = foo(b)
FIRST_VAR = '^\w+'
LINE_TO_INSERT = ' = bar(42)\n'
'''Insert a line with 'FIRST_VAR + LINE_TO_INSERT' after each PATTERN_OF_LINEI made a gist with all the files and scripts.
Go through a file looking for PATTERN_OF_LINE
if found, insert a line just after with 'FIRST_VAR + LINE_TO_INSERT'
Args:
path: a path to a file to search and insert lines if a match is found
Returns:
None
'''
from re import escape
from re import search
fin = open(path, 'r')
open('output', 'w').close() # clear file before processing
fout = open('output', 'w')
for line in fin:
fout.write(line)
match = search(PATTERN_OF_LINE, line)
if match:
res = search(FIRST_VAR, line)
if res:
fout.write(res.group(0) + LINE_TO_INSERT)
fin.close()
fout.close()
# save file
ftemp = open('output', 'r')
try:
open(path, 'w').close() # clear file before processing
except:
print('cannot write in file:', path)
ftemp.close()
return None
f = open(path, 'w')
for line in ftemp:
f.write(line)
f.close()
ftemp.close()
return None