What is the best approach in editing script files with other script files ?

3 次查看(过去 30 天)
Suppose I have this in a script(A) currently:
temp1 = 435;
variable4 = 99990;
something = 56;
Using another script(B) I want this output:
new = 145;
var = 776;
thing = 9;
I have a excel spreadsheet that that has 1 column of the old variable names from A and another column that contains the new varibale name and a 3rd column with the new values. I can already change the variable names, but how do I find and replace the old values with the new values? I was thinking about using a strfind to find where the '=' and find where ';' is and then grab everything in between and replace it, but i think that this isnt the best approach for something like this. Opinions?
  1 个评论
Cedric
Cedric 2015-8-14
编辑:Cedric 2015-8-14
Are the former values fixed/constant or can they vary? If everything is fixed, the best approach is probably STRREP. If they can vary, then the best approach is certainly REGEXPREP.

请先登录,再进行评论。

采纳的回答

Cedric
Cedric 2015-8-14
编辑:Cedric 2015-8-14
You can do something along the following line. As you don't have 4 columns in your Excel file, I assume that the former values can be anything and I use REGEXPREP:
originalLocator = 'Original' ; % Folder where the original M-Files are stored.
modifiedLocator = 'Modified' ; % Folder where the modified M-Files will be saved.
replacementsLocator = 'replacements.xlsx' ;
if ~exist( modifiedLocator, 'dir' )
mkdir( modifiedLocator ) ;
end
[~,~,repArray] = xlsread( replacementsLocator ) ;
D = dir( fullfile( originalLocator, '*.m' )) ;
for fId_in = 1 : numel( D )
% - Read original.
content = fileread( fullfile( originalLocator, D(fId_in).name )) ;
% - Apply modifications.
for vId = 1 : size( repArray, 1 )
pattern = sprintf( '%s\\s*=\\s*[^;]+;', repArray{vId,1} ) ;
replacement = sprintf( '%s = %d ;', repArray{vId,2}, repArray{vId,3} ) ;
content = regexprep( content, pattern, replacement, 'once' ) ;
end
% - Output modified file.
fId_out = fopen( fullfile( modifiedLocator, D(fId_in).name ), 'w' ) ;
fwrite( fId_out, content ) ;
fclose( fId_out ) ;
end
Note about the pattern that is built with the first SPRINTF call: it has the following structure (when the variable name is temp1):
temp1\s*=\s*[^;]+;
which matches:
  • Literal 'temp1'
  • Followed by 0 or more white space characters (\s*)
  • Followed by literal '='
  • Followed by 0 or more white space characters (\s*)
  • Followed by one or more character that is not in the set ';' ([^;])
  • Followed by the literal ';'
We could make it less specific, but then we would take the risk that it matches something else before (not after because we use the 'once' parameter in the call to REGEXPREP, so replacement is applied only to the first match).
  2 个评论
Rodriguez Pham
Rodriguez Pham 2015-8-14
Hey Cedrick could you show me an example output for the section where we apply the pattern, replacement, and regexprep?
lets say we were changing: temp1 = 435; into new = 145; what would the outputs of pattern and replacement be? I am trying some small examples in my command window and it isnt working out for me.
Thanks!
Cedric
Cedric 2015-8-14
编辑:Cedric 2015-8-14
Hi Rodriguez. I am not sure that I understand what you are asking. My answer does the following:
  1. Open the Excel file (you may have to adjust the file name to your case), read a 3 columns cell array of replacement rules and store it in a cell array named repArray (it is the "raw" output of XLSREAD).
  2. Get the listing of M-Files (*.m) of the folder with the original M-Files.
  3. Iterate over files.
For each file, the following is done:
  1. Read the file as a string.
  2. Iterate over rows of the array of replacement rules, and perform replacements.
  3. Export the modified file content to a new file in an output folder (so the original files are left unaltered, just in case).
Now the replacement pattern is built dynamically with the first call to SPRINTF, where you see that I insert the variable name at the beginning of the pattern, and then I create the pattern with a static string (where I must escape the backslashes so they are not interpreted by SPRINTF).
This means that you don't have to hard-code any variable name in the pattern. It is built automatically from the content of the Excel file.
I am attaching an example (Example.zip). The best that you can do is to use the debugger to run it step by step, so you can observe how the pattern is built, how the replacement string is built, etc.
To run it in the debugger, open main.m, place your cursor on the line:
originalLocator = 'Original' ;
press F12. You see that by pressing F12 you can toggle a red dot on the left of the line. This is a break point. If you run the code now, MATLAB executes it up to the break point (just before it actually), and stops. You are in the debugger. A green arrow indicates the next line to be executed, and the prompt of the command window starts with the letter K (for Keyboard mode). If you press F10, the line is executed (it is a "step" and you can also do it by clicking on the Step button in the editor ribbon). Now you see that the variable originalLocator is defined (the line was executed). You can see that in the Workspace, or just by typing the variable name in the command window. By pressing F10 (or step) successively, you can follow the functioning of the program. If you go on until the variable sepArray is defined, you can display it and see replacement rules. Then you go on until variable pattern is defined, and you see that it inserted the first variable name in the pattern. If you go on this way, you will see MATLAB looping over replacement rules, save the first file (that will be present in your file system), and loop to the second file.
Hope it helps!

请先登录,再进行评论。

更多回答(1 个)

Muthu Annamalai
Muthu Annamalai 2015-8-14
编辑:Muthu Annamalai 2015-8-14
@Rodriguez, and @Cedric I propose an alternative way to look at the question; it would be nice to have same script return different results based on some updates.
I wonder if the updates could come from a MAT file or a CSV file, like,
function data = script_fcn()
latest_data = load('fname.mat') %or csvread(...)
data_modified = process( data ) %some processing
data = data_modified.fieldx;
end
and ofcourse the user can update the MAT/CSV from another script.
  1 个评论
Cedric
Cedric 2015-8-14
Ah yes, well I assumed that it was some sort of one-shot code refactoring operation. Otherwise I think that we can discourage the OP to perform this kind of operations on a regular basis.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 File Operations 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by