Merge specific text files - matlab

I have a problem in my code. I am using some loops in order to create mulptile .txt files with specific names, eg mR1.txt, mR2.txt,...mR100.txt. After that I merge them into one file with the following commands:
name=regexp(fileread('names.txt'), '\r?\n', 'split') .';
file1=regexp(fileread('data.txt'), '\r?\n', 'split') .';
.....
for n=1:numel(name);
for z=1:size(file1)
........ %making caluclations
FP=fopen(sprintf('mR%g0.txt',z),'wt');
fprintf(FP,'%s\t',file1{z},num2str(number),num2str(number);
fclose(FP);
txtFiles = dir('mR*.txt') ; % get the text files in the present folder
N = length(txtFiles) ; % Total number of text files
iwant = cell(N,1) ; % initlaize the data required
% loop for each file
for i = 1:N
thisFile = txtFiles(i).name ;
iwant{i} = importdata(thisFile) ; % read data of the text file
end
iwant = cell2mat(iwant) ;
outFile = strcat('finalR',num2str(n),'.txt') ;
dlmwrite(outFile,iwant,'delimiter','\t')
end
end
I would like to create for each iteration M1_mR1.txt,...,M1_mr100.txt, and M1_mR1.txt,..., M2_mR100.txt. After that I would like to merge all the files that Have prefix M1_.....txt into one file and all the files that Have prefix M2_.....txt into one file.
How could I do this?

This can be done in multiple ways.
Note about sorting: The default sorting in files will give higher value to file2 than file100, so you need to sort by actual number value. This is done by converting the filename numbers to first code and second code, and then sort by the second code with sortrows.
So this will solve the problem:
clear
textfiles_dir=dir('M*_mR*.txt');
textfiles_name={textfiles_dir.name}; %group the filenames into cell array
textfiles_codes=cellfun(#(fname)textscan(fname,'M%d_mR%d.txt'),textfiles_name,'Uniform',false);
textfiles_codes=cell2mat(cat(1,textfiles_codes{:})); %separate bw first and second code
disp(textfiles_codes)
[sorted_codes,orig_idx]=sortrows(textfiles_codes,2); %sort by second code
first_codes=sorted_codes(:,1);
second_codes=sorted_codes(:,2);
unique_firstcodes=unique(first_codes);
for ifirstcode=1:length(unique_firstcodes)
firstcode=unique_firstcodes(ifirstcode);
fprintf('firstcode=%d: ',firstcode)
target_name=sprintf('Merged%d.txt',firstcode);
f_target=fopen(target_name,'w');
idxs=orig_idx(first_codes==firstcode); % already sorted in increasing order
for i=1:length(idxs)
idx=idxs(i);
fname=textfiles_name{idx};
fprintf(' %s ',fname)
f_src=fopen(fname,'r');
src_text=fread(f_src,'*char')';
fclose(f_src);
fwrite( f_target,src_text);
end
fclose(f_target);
fprintf('\n')
end
fprintf('Done!\n')

Related

How to merge two text files in Matlab and duplicate the resulting file?

I need to generate a number of text (or dat) files to be fed into another software. I have two text files (aa.txt and bb.txt) and an equation that generates random numbers.
The produced text (or .dat) file is to be comprised of three parts:
1- The contents of aa.txt.
2- Randomly generated numbers.
3- the contents of bb.txt.
the files' contents are :
aa.txt -->
first file ,,, first line
First file ,,, second line
1234.1234
bb.txt -->
second file ,,, first line
second file ,,, second line
6789.6789
I wrote the following code, but it will only produce one file with the contents of the first source file (aa.txt).
Why do I end up with 1 file?
Why is the variable A not written in the generated file?
NOF =3; % start with a goal to produce 3 files (small scale)
for ii = 1:NOF
ffid= fopen ('aa.txt','r'); % open the first source file (aa.txt), the idntifier is ffid
df = fopen (['file' sprintf('%d',ii) '.txt'], 'a'); % open a new (destination) file the identifier is df
line=fgets (ffid); % Read line from first source file
while ischar (line)
fprintf ('%s\n',line);
line =fgets (ffid);
fprintf (df , line); % write the newly-read line from first file to the destination file
end
fclose (ffid); % closing the first source file
A=randn(2,2); % this is just a randonly generated value for checking purposes and will be replaced later with a many sets of equations
save (['file' sprintf('%d',ii) '.txt'],'A', '-append');
sfid=fopen ('bb.txt','r'); % open the second source file, the idntifier is sfid
line2=fgets (sfid); % Read line from source file
while ischar (line2)
fprintf ('%s\n',line2);
line2 =fgets (sfid);
fprintf (df , line2);
end
fclose (sfid); % closing the first source file
end
fclose (df);
fclose('all');
This should basically produce what you are looking for:
for ii = 1:3
% Create the output file...
fid_out = fopen(['file' num2str(ii) '.txt'],'w');
% Read the whole content of the first file into the output file...
fid_aa = fopen('aa.txt','r');
while (~feof(fid_aa))
fprintf(fid_out,'%s\n',fgetl(fid_aa));
end
fclose(fid_aa);
% Generate the random matrix and write it to the output file...
random = cellstr(num2str(randn(2)));
for jj = 1:numel(random)
fprintf(fid_out,'%s\n',random{jj});
end
% Read the whole content of the second file into the output file...
fid_bb = fopen('bb.txt','r');
while (~feof(fid_bb))
fprintf(fid_out,'%s\n',fgetl(fid_bb));
end
fclose(fid_bb);
% Finalize the output file...
fclose(fid_out);
end
Given, for example, the file aa.txt with the following content:
A - Line 1
A - Line 2
A - Line 3
and the file bb.txt with the following content:
B - Line 1
B - Line 2
B - Line 3
the output files would present the structure below:
A - Line 1
A - Line 2
A - Line 3
0.18323 0.94922
-1.0298 0.30706
B - Line 1
B - Line 2
B - Line 3
For the sake of optimization, since I/O is very expensive, I suggest you to read the content of aa.txt and bb.txt only once outside the loop that produces the output files, and save their content into cell arrays. Here is how:
fid = fopen('file.txt','r');
data = cell(0);
while (~feof(fid))
data{end+1} = fgetl(fid);
end
Inside the loop that produces the output files, you can then iterate the cell array contents in order to print them:
for jj = 1:numel(data)
fprintf(fid_out,'%s\n',data{jj});
end

Modify the value of a specific position in a text file in Matlab

AIR, ID
AIR.SIT
50 1 1 1 0 0 2 1
43.57 -116.24 1. 857.7
Hi, All,
I have a text file like above. Now in Matlab, I want to create 5000 text files, changing the number "2" (the specific number in the 3rd row) from 1 to 5000 in each file, while keeping other contents the same. In every loop, the changed number is the same with the loop number. And the output in every loop is saved into a new text file, with the name like AIR_LoopNumber.SIT.
I've spent some time writing on that. But it is kind of difficult for a newby. Here is what I have:
% - Read source file.
fid = fopen ('Air.SIT');
n = 1;
textline={};
while (~feof(fid))
textline(n,1)={fgetl(fid)};
end
FileName=Air;
% - Replace characters when relevant.
for i = 1 : 5000
filename = sprintf('%s_%d.SIT','filename',i);
end
Anybody can help on finishing the program?
Thanks,
James
If your file is so short you do not have to read it line by line. Just read the full thing in one variable, modify only the necessary part of it before each write, then write the full variable back in one go.
%% // read the full file as a long sequence of 'char'
fid = fopen ('Air.SIT');
fulltext = fread(fid,Inf,'char') ;
fclose(fid) ;
%% // add a few blank placeholder (3 exactly) to hold the 4 digits when we'll be counting 5000
fulltext = [fulltext(1:49) ; 32 ; 32 ; 32 ; fulltext(50:end) ] ;
idx2replace = 50:53 ; %// save the index of the characters which will be modified each loop
%% // Go for it
baseFileName = 'AIR_%d.SIT' ;
for iFile = 1:1000:5000
%// build filename
filename = sprintf(baseFileName,iFile);
%// modify the string to write
fulltext(idx2replace) = num2str(iFile,'%04d').' ; %//'
%// write the file
fidw = fopen( filename , 'w' ) ;
fwrite(fidw,fulltext) ;
fclose(fidw) ;
end
This example works with the text in your example, you may have to adjust slightly the indices of the characters to replace if your real case is different.
Also I set a step of 1000 for the loop to let you try and see if it works without writing 1000's of file. When you are satisfied with the result, remove the 1000 step in the for loop.
Edit:
The format specifier %04d I gave in the first solution insure the output will take 4 characters, and it will pad any smaller number with zero (ex: 23 => 0023). It is sometimes desirable to keep the length constant, and in your particular example it made things easier because the output string would be exactly the same length for all the files.
However it is not mandatory at all, if you do not want the loop number to be padded with zero, you can use the simple format %d. This will only use the required number of digits.
The side effect is that the output string will be of different length for different loop number, so we cannot use one string for all the iterations, we have to recreate a string at each iteration. So the simple modifications are as follow. Keep the first paragraph of the solution above as is, and replace the last 2 paragraphs with the following:
%% // prepare the block of text before and after the character to change
textBefore = fulltext(1:49) ;
textAfter = fulltext(51:end) ;
%% // Go for it
baseFileName = 'AIR_%d.SIT' ;
for iFile = 1:500:5000
%// build filename
filename = sprintf(baseFileName,iFile);
%// rebuild the string to write
fulltext = [textBefore ; num2str(iFile,'%d').' ; textAfter ]; %//'
%// write the file
fidw = fopen( filename , 'w' ) ;
fwrite(fidw,fulltext) ;
fclose(fidw) ;
end
Note:
The constant length of character for a number may not be important in the file, but it can be very useful for your file names to be named AIR_0001 ... AIR_0023 ... AIR_849 ... AIR_4357 etc ... because in a list they will appear properly ordered in any explorer windows.
If you want your files named with constant length numbers, the just use:
baseFileName = 'AIR_%04d.SIT' ;
instead of the current line.

Loading multiple text files from a single directory in matlab

First time here so please be gentle
So the basic idea is i have folders with just txt files that has about 20000 points each. I only want specific intervals from each of them.
I have a made a single file with the ranges for that looks like this
. 2715 2955
1132 1372
each row representing the range i want in one file
I want to batch load all the files and export the just the ranges of each. Ive lost too much sleep over this please help
dirName = '*'; %# folder path
files = dir( fullfile(dirName,'*.txt') ); %# list all *.xyz files
files = {files.name}' ; %'# file names
data = cell(numel(files),1) ; %# store file contents
for u=1:numel(files)
A=files{u} ; %# full path to file
files{u};
STR1 = A
B=load(STR1);
end
This is all i have come up with in 2 days. im new to matlab
Thanks
A very good help is the matlab help of fscanf, http://www.mathworks.co.uk/help/matlab/ref/fscanf.html. Also, in your load you don't have the path. Replace the last two lines in your for loop with:
STR1 = [dirName A]
fileID = fopen(STR1,'r');
formatSpec = '%f';
B = fscanf(fileID,formatSpec)
Or try:
delim = ' ';
nrhdr = 0;
STR1 = [dirName A]
A = importdata(STR1, delim, nrhdr);
A.data will be your data, I'm assuming no header lines.

Batch Change File Names in Matlab

I have 200 JPEG images numbered from 1200 to 1399. How do I change their names from 1200.jpg-1400.jpg to 1.jpg-200.jpg, while keeping the original order of the image names?
This is a problem which can be tackled more efficiently in bash or other shell scripting languages. Probably, it can even be solved just via a single shell find.
Anyway, matlab can also do the job.
Consider this.
list = dir('./stack*.png'); % # assuming the file names are like stack1200.jpg
offset = -1200; # % numbering offset amount
for idx = 1:length(list) % # we go through every file name
name = list(idx).name;
number = sscanf(name,'stack%f.png',1); % # we extract the number
movefile(name,['stack' num2str(number + offset) '.png' ]); % # we rename the file.
end
I have find this solution which is quiet straightforward.
Pathfold= ('Path\to\images\');
dirData = dir('path\to\images\*.jpg');
fileNames = {dirData.name};
for i = 1:size(fileNames)
newName = sprintf('%d.jpg',i);
movefile(fileNames{i},[Pathfold , newName]) %# Rename the file
end

Extract variables from a textfile in matlab

I have a large text file (~3500 lines) which contains output data from an instrument. This consists of repeated entries from different measurements which are all formatted as follows:
* LogFrame Start *
variablename1: value
variablename2: value
...
variablename35: value
* LogFrame End *
Each logframe contains 35 variables. From these I would like to extract two, 'VName' and 'EMGMARKER' and put the associated values in columns in a matlab array, (i.e. the array should be (VName,EMGMARKER) which I can then associate with data from another output file which I already have in a matlab array. I have no idea where to start with this in order to extract the variables from this file, so hence my searches on the internet so far have been unsuccessful. Any advice on this would be much appreciated.
You could use textscan:
C = textscan(file_id,'%s %f');
Then you extract the variables of interest like this:
VName_indices = strcmp(C{1},'VName:');
VName = C{2}(VName_indices);
If the variable names, so 'VName' and 'EMGMARKER' , are always the same you can just read through the file and search for lines containing them and extract data from there. I don't know what values they contain so you might have to use cells instead of arrays when extracting them.
fileID = fopen([target_path fname]); % open .txt file
% read the first line of the specified .txt file
current_line = fgetl(fileID);
counter = 1;
% go through the whole file
while(ischar(current_line))
if ~isempty(strfind(current_line, VName))
% now you find the location of the white space delimiter between name and value
d_loc = strfind(current_line,char(9));% if it's tab separated - so \t
d_loc = strfind(current_line,' ');% if it's a simple white space
variable_name{counter} = strtok(current_line);% strtok returns everything up until the first white space
variable_value{counter} = str2double(strtok(current_line(d_loc(1):end)));% returns everything form first to second white space and converts it into a double
end
% same block for EMGMARKER
counter = counter+1;
current_line = fgetl(fileID);% next line
end
You do the same for EMGMARKER and you have cells containing the data you need.