I have a programme (in exe format) used to create one image result. Usually, when I use it, I copy the executable in a folder of images, and I type the command on msdos console. Now, i want to try to automatize that with different folders, each one with its images.
What I want to do is that matlab execute the programme in every folder. What I've been doing is the following:
Path= 'C:\Tools\'
a= dir (fullfile(Path,'*'))
fileNames = { a.name };
for k = 1:length(fileNames)
system('C:\programme.exe')
end
It's not working properly. Can be because is not executing the programme in each folder?
Thanks in advance!
Well you need to actually move your programme.exe into the folder first so maybe something like:
Path= 'C:\Tools\'
a= dir (fullfile(Path,'*'))
fileNames = { a.name };
for k = 1:length(fileNames)
copy('C:\programme.exe', [fileNames, '\programme.exe'])
system('programme.exe')
end
You might have some other problems though, for example you only want folder names when you call dir so you might want to ignore any name with a . in it:
Path= 'C:\Tools\'
a= dir (fullfile(Path,'*'))
Names = { a.name };
ind = cell2mat(cellfun(#(x)(any(ismember(x,'.'))),b,'uni',0));
folders = Names(~ind)
for k = 1:length(folders)
copy('C:\programme.exe', [fileNames, '\programme.exe'])
system('programme.exe')
end
But I think you'd probably rather use move than copy which I'll leave for you to do
Looks like changing the working directory would do the trick:
http://www.mathworks.com/help/matlab/ref/cd.html
cd(Path)
Related
In the below code I am trying to sort files based on a string within the name. I've been piecing this together with google searches and community help (I'm very new at matlab). Right now I'm getting two odd errors. First, when I try and make a folder, it creates some file (highlighted filein picture that I can't open and the wav files that should have been moved to the folder disappear.
I'm also having an issue where the code renames the first two data files moved to "01" and "01 (1)" and I have no idea why.
DirIn = 'C:\Folder\Experiment' %set incoming directory
eval(['filelist=dir(''' DirIn '/*.wav'')']) %get file list
for i = 1:length(filelist);
Filename = filelist(i).name
name = strsplit(Filename, '_');
newStr = extractBetween(name,7,8);
if strcmp(newStr,'01')
DirOut = fullfile(DirIn, '01');
mkdir DirIn DirOut
movefile(fullfile(filelist(i).folder, filelist(i).name), DirOut);
end
end
This should work:
DirIn = 'C:\Folder\Experiment'; %set incoming directory
filelist=dir(fullfile(DirIn, '*.wav')); %get file list
DirOut = fullfile(DirIn, '01');
for i = 1:length(filelist);
Filename = filelist(i).name
newStr = Filename(7:8);
if strcmp(newStr,'01')
if ~exist(DirOut)
mkdir(DirOut)
end
movefile(fullfile(filelist(i).folder, filelist(i).name), DirOut);
end
end
Firstly, you don't need eval to get the file list. eval impact performance significantly. The below is what you should have done:
filelist=dir(fullfile(DirIn, '*.wav'));
You don't need strsplit or extractBetween since you only intend to extract a part of the string by indexing, i.e. the 7th and 8th characters, you may do this:
newStr = Filename(7:8);
To use variable as an input, you need to use mkdir as a function rather than console command:
mkdir(DirOut)
Lastly, a bit of optimisation. Since DirOut is constant, you can take it outside the loop. You may also want to check if DirOut has already been created to avoid the warning message and overhead in mkdir.
There is no issue with movefile.
Couple things go wrong, first, it is not recommended to use eval. In this case you can just create a character array to pass to dir as follows:
filelist = dir([DirIn '/*.wav'])
Then, you have a strplit that appears to do nothing, since it looks like your files don't have '_' in them, so name will just return Filename. But that is not the issue, since you are using extractBetween on the Filename.
The following does not what you think it does,
mkdir DirIn DirOut
will create two directories named DirIn and DirOut in the current working directory of Matlab. To create the directories you want, use:
mkdir(DirOut)
Since the output directory did not exist before, I suspect Matlab moved the file to the input directory, and renamed it to 01, if you manually add the extension .wav it should be one of the original files.
The goal of my code is to look into a certain folder and create a new text file with a list of names of all the files that aren't empty in that folder written to a new file, and the list of names of all the empty files (no text) into another folder. My current code is only able to create a new text file with a list of names of all the files (regardless of its content) written to a new file. I want to know how to set up if statement regarding the content of the file (array).
function ListFile
dirName = '';
files = dir(fullfile(dirName,'*.txt'));
files = {files.name};
[fid,msg] = fopen(sprintf('output.txt'),'w+t');
assert(fid>=0,msg)
fprintf(fid,'%s\n',files{:});
fclose(fid);
EDIT: The linked solution in Stewie Griffin's comment is way better. Use this!
A simple approach would be to iterate all files, open them, and check their content. Caveat: If you have large files, this approach might be memory intensive.
A possible code for that could look like this:
function ListFile
dirName = '';
files = dir(fullfile(dirName, '*.txt'));
files = {files.name};
fidEmpty = fopen(sprintf('output_empty_files.txt'), 'w+t');
fidNonempty = fopen(sprintf('output_nonempty_files.txt'), 'w+t');
for iFile = 1:numel(files)
content = fileread(files{iFile})
if (isempty(content))
fprintf(fidEmpty, '%s\n', files{iFile});
else
fprintf(fidNonempty, '%s\n', files{iFile});
end
end
fclose(fidEmpty);
fclose(fidNonempty);
I have two non-empty files nonempty1.txt and nonempty2.txt as well as two empty files empty1.txt and empty2.txt. Running this code, I get the following outputs.
Debugging output from fileread:
content =
content =
content = Test
content = Another test
Content of output_empty_files.txt:
empty1.txt
empty2.txt
Content of output_nonempty_files.txt:
nonempty1.txt
nonempty2.txt
Matlab isn't really the optimal tool for this task (although it is capable). To generate the files you're looking for, a command line tool would be much more efficient.
For example, using GNU find you could do
find . -type f -not -empty -ls > notemptyfiles.txt
find . -type f -empty -ls > emptyfiles.txt
to create the text files you desire. Here's a link for doing something comparable using the windows command line. You could also call these functions from within Matlab if you want to using the system command. This would be much faster than iterating over the files from within Matlab.
I have a lot of .fig files that are named like this: 20160922_01_id_32509055.fig, 20160921_02_id_53109418.fig and so on.
So I thought that I create a script that loop through all the .fig files in the folder and group(copy) them into another folder(s) based on the last number in the file name. The folder is created based on the id number. Is this possible?
I have been looking on other solutions involving looping through folders but I am totally fresh. This would make it easier for me to check the .fig files while I am learning to do other stuff in Matlab.
All is possible with MATLAB! We can use dir to get all .fig files, then use regexp to get the numeric part of each filename and then use copyfile to copy the file to it's new home. If you want to move it instead, you can use movefile instead .
% Define where the files are now and where you want them.
srcdir = '/my/input/directory';
outdir = '/my/output/directory';
% Find all .fig files in the source directory
figfiles = dir(fullfile(srcdir, '*.fig'));
figfiles = {figfiles.name};
for k = 1:numel(figfiles)
% Extract the last numeric part from the filename
numpart = regexp(figfiles{k}, '(?<=id_)\d+', 'match', 'once');
% Determine the folder we are going to put it in
destination = fullfile(outdir, numpart);
% Make sure the folder exists
if ~exist(destination, 'dir')
mkdir(destination)
end
% Copy the file there!
copyfile(fullfile(srcdir, figfiles{k}), destination)
end
Here's an example how to identify and copy the files. I'll let you do the for loop :)
>> Figs = dir('*.fig'); % I had two .fig files on my desktop
>> Basename = strsplit(Figs(1).name, '.');
>> Id = strsplit(Basename{1}, '_');
>> Id = Id{3};
>> mkdir(fullfile('./',Id));
>> copyfile(Figs(1).name, fullfile('./',Id));
Play with the commands to see what they do. It should be straightforward :)
I write code where I load a lot of project data. I want to keep my pathnames in the code relative to some location of this project on the disk, i.e. not having it configured or hard-coded.
Is there function in matlab to do some like this?
In python I would write:
ROOT = os.path.dirname(__file__)
The best way to do this is to combine fileparts with mfilename('fullpath'). (All examples assume the executing m-file containing these statements lives in /home/suever/code/stackoverflow.m)
mfiledir = fileparts(mfilename('fullpath'));
/home/suever/code
Then you can use fullfile to construct any paths you need from that. Now if you have a file (data.mat) stored in the same directory:
filename = fullfile(mfiledir, 'data.mat');
/home/suever/code/data.mat
Of if the file is actually in the parent directory.
filename = fullfile(mfiledir, '..', 'data.mat');
/home/suever/data.mat
If you want just the parent directory that an m-file is in, you can apply fileparts twice and only keep the second output.
[~, reldir] = fileparts(fileparts(mfilename('fullpath')));
code
I would recommend the use of full paths in the first examples as those are completely independent of the user's current working directory.
A better recipe to organize your code is to have a function like this:
function [ path ] = get_path()
path = [regexprep(mfilename('fullpath'), ['\' filesep '[\w\.]*$'],'') filesep];
end
You drop it inside +foo/get_path.m file and than call something like foo.get_path() that returns the path to +foo folder.
I have the following problem in Matlab.
I'm opening an existing file with this line:
fileID = fopen(filename,'r');
I then create a new file with this line:
fid=fopen('output.txt','w');
That works just fine. The problem is, I don't want it to be called "output". I would like to call it using the original filename and adding a bit of string to it, like this: "filename_new.txt". The output file also has to be a .txt file, regardless of what the original one was.
I know I can get the name of the original file into string using this:
[pathstr, name, ext] = fileparts(filename)
but I have no idea where to go from there.
So to sum it up, the new file should be called "name_new.txt".
I have a feeling this is either trivial to you guys or you're gonna tell me it's not actually possible this way. Either way, I'd be grateful for any help.
You can try this:
filename_out = [filename(1:end-4),'_new.txt'];
fid=fopen(filename_out,'w');
filename(1:end-4) is a quick and easy way to remove the .txt ending. If you know that it'll all be txt-files, this should suffice.
With the [] you can combine the two strings, in this case appending a _new.txt
http://www.mathworks.com/help/matlab/ref/fullfile.html
Try then
f = fullfile(pathstr, strcat(name,'_new.',ext))
%% Rename whole *copy.png -> .png by JYJ
root_dir = '/Users/Yoojeong/Desktop/stims/png';
%retrieve the name of the files only
listdir = dir(fullfile(root_dir, '*.png'));
% i = 1;
for i = 1:length(listdir)
[pathname, filename, extention] = fileparts(listdir(i).name);
%the new name
newFilename = [filename(1:end-5),'.png'];
movefile(fullfile(root_dir, listdir(i).name), fullfile(root_dir,newFilename))
end