user2066183
user2066183

Reputation:

Edit multiple Matlab .m files using Matlab

I have some 50+ m files that worked in a previous driver version but are outdated for the newer driver version. As a result, I need to find and replace various variable or field names, and sometimes edit variable inputs for all these files. For example, I'd like to find the line

src.aaaa = 100;

and replace it to:

src.bbbb = 100;

another example is to replace:

vid = videoinput('xxxx' ,1, 'yyy')

with:

vid = videoinput('kkkkkk' ,1, 'zzzz')

I've searched and found this discussion, that allows to search in multiple files, but not really edit or replace anything. I can handle matlab so I'm looking for a way to do that in matlab. Any ideas?

Upvotes: 4

Views: 3757

Answers (4)

MechtEngineer
MechtEngineer

Reputation: 597

Ergodicity replied with some great code, but:

  • Some comments are in German rather than English
  • There is a general lack in commenting, which makes it hard to understand

I have attempted to fix these problems with the code below (I can't seem to get the code to display in MATLAB format very well using "language: lang-matlab", so paste it into MATLAB for easier reading):

close all;
clear all;
clc;
%% Parameters
% The directory in which to replace files. Currently this code does not modify files in
% sub-directories
directory           = 'C:\Users\Name\Wonderful code folder';
% The string that will be replaced
oldString           = sprintf('terrible mistake');
% The replacement string
newString           = sprintf('all fixed now');
% The file name condition - what type of files will be examined
% It must contain any of the English character set (letters, numbers or underscore
% character i.e. a-zA-Z_0-9) and ends with a ".m" MATLAB extension (use \.txt for text files)
regularExpression   = '[\w]+\.m';

%% Determine files to update, and update them as necessary
% Change the current directory to the user-specified one
cd(directory)
% Put the details of all files and folders in that current directory into a structure
allFilesInDirectory = dir;
% Initialise indexes for files that do and do not contain oldString
filesWithStringIndex = 1;
filesWithoutStringIndex = 1;
% For the number of files and folders in the directory
for idx = 1 : length(allFilesInDirectory)

    % If the file name contains any of the English character set (letters, numbers or
    % underscore character i.e. a-zA-Z_0-9) and ends with a ".m" filetype...
    if (~isempty ( regexp(allFilesInDirectory(idx).name, '[\w]+\.m','match') ))

        % Open the file for reading
        fileIdRead  = fopen(allFilesInDirectory(idx).name, 'r');

        % Extract the text
        fileText = fscanf(fileIdRead,'%c');

        % Close the file
        fclose(fileIdRead);

        % Search for occurrences of oldString
        occurrences = strfind(fileText,oldString);

        % If an occurrence is found...
        if ~isempty(occurrences)

            % Replace any occurrences of oldString with newString
            fileTextNew = strrep(fileText, oldString, newString);

            % Open the file for writing
            fileIdWrite = fopen(allFilesInDirectory(idx).name, 'w');

            % Write the modified text
            fprintf(fileIdWrite, '%c', fileTextNew);

            % Close the file
            fclose(fileIdWrite);

            % Update the list of files that contained oldString
            filesWithString{filesWithStringIndex} = allFilesInDirectory(idx).name;

            % Update the index for files that contained oldString
            filesWithStringIndex = filesWithStringIndex + 1;

        else
            % Update the list of files that did not contain oldString
            filesWithoutString{filesWithoutStringIndex} = allFilesInDirectory(idx).name;

            % Update the index for files that did not contain oldString
            filesWithoutStringIndex = filesWithoutStringIndex + 1;

        end
    end
end
%% Display what files were changed, and what were not
% If the variable filesWithString exists in the workspace
if exist('filesWithString','var')
    disp('Files that contained the target string that were updated:');
    % Display their names
    for i = 1:filesWithStringIndex-1, disp(filesWithString{i}); end
else
    disp('No files contained the target string');
end
% Insert a clear line between lists
disp(' ');
% If the variable fileWithoutString exists in the workspace
if exist('filesWithoutString','var')
    disp('Files that were not updated:');
    % Display their names
    for j = 1:filesWithoutStringIndex-1, disp(filesWithoutString{j}); end
else
    disp('All files contained the target string.');
end

Upvotes: 1

Semjon Mössinger
Semjon Mössinger

Reputation: 1890

The m-File implementing Sekkou's suggestion:

clear all;
clc;


%% Parameter

directory           = 'd:\xxx';
oldString           = 'the old text';
newString           = 'the new text';
regularExpression   = '[\w]+\.m';


%% Determine files to manipulate

cd(directory)

allFilesInDirectory = dir;


%% Manipulieren der verweneten Dateien

disp('Manipulated Files:');

for idx = 1 : length(allFilesInDirectory)

    if (~isempty ( regexp(allFilesInDirectory(idx).name, '[\w]+\.m','match') ))

        disp(allFilesInDirectory(idx).name);

        % Read and manipulate Text
        fileIdRead  = fopen(allFilesInDirectory(idx).name, 'r');
        fileText    = fscanf(fileIdRead,'%c');

        fileTextNew = strrep(fileText, oldString, newString);

        fclose(fileIdRead);


        % Write Text
        fileIdWrite = fopen(allFilesInDirectory(idx).name, 'w');

        fprintf(fileIdWrite, '%c', fileTextNew);

        fclose(fileIdWrite);
    end

end

Upvotes: 1

bdecaf
bdecaf

Reputation: 4732

A bit outside the box - but I would use the sed command - it does exactly what you want and is quick on it, but is you need to call it with system and build the command string. If you are on windows you may need to install it through msys or cygwin.

Upvotes: 2

Sekkou527
Sekkou527

Reputation: 474

You could use the 'Find Files' dialog that you posted (Ctrl-Shift-F) to find each file you are looking for and then 'Find and Replace' (Ctrl+F) the specific lines you want to change.

As an example, find the file with src.aaaa = 100; using Ctrl+Shift+F. Then Ctrl+F and add the src.aaaa = 100; to the upper textbox and src.bbbb = 100; to the lower textbox.

From your post, it is unclear as to whether or not this would be feasible since I do not know how many different lines you would like to change in these m-files. How many are there? Are the m-files similar or are they all different?

If there are specific variables you are searching for, you could write a script to loop search through all the m-files using the dir function. Read the m-file into a string variable using fscanf. Then replace the variable in the string using strrep. And finally using fprintf to write to a new .m file with the corrected variables.

Refer to:

Upvotes: 3

Related Questions