Using strepp on a textfile with replacement from array.

EDIT due to comments (learning to ask better questions)
Inputs
1)I have an EXCEL array of dimensions 322x8 containing numeric data of a specific format (3.548E-07). e.g.
if true
H+ Ca Mg HCO3 Na K SO4 Cl
3.548E-07 1.183E-01 3.222E-02 1.560E-02 5.771E-01 0.000E+00 2.666E-02 8.113E-01
continued for 321 more rows
end
2)I have a text template file and contained within are 8 strings (%1 to %8) e.g.
if true
'GASES'
'*'
'SURFACE COMPLEXES'
'*' 'no mineral' 'xoh'
'SPECIES W/ Kd and DECAY decay constant(1/s)'
'*' 0.0 0.0 0.0
'EXCHANGEABLE CATIONS' 0
' master convention ex. coef.'
'*' 0 0 0.000e+000
'------------------------------------------------------------------------------'
'INITIAL AND BOUNDARY WATER TYPES'
1 1 !niwtype, nbwtype = number of initial and boundary waters
1 30.0 !iwtype initial, temp (C)
' icon guess ctot constrain' ! Modern seawater
'h2o' 1 1.000d+0 1.000d+0 ' ' 0 !
'h+' 3 %1 %1 ' ' 0 !pH=8.22
'ca+2' 1 %2 %2 ' ' 0
'mg+2' 1 %3 %3 ' ' 0
'hco3-' 1 %4 %4 ' ' 0
'na+' 1 %5 %5 ' ' 0
'k+' 1 %6 %6 ' ' 0
'so4-2' 1 %7 %7 ' ' 0
'cl-' 1 %8 %8 ' ' 0
'*' 0 0.0 0.0 ' ' 0
1 30.0 !iwtype boundary, temp (C)
end
Process and Output
1) I need to replace the 8 strings from the template file with the row data. I need to repeat this 322 times and save each newly created text file with exactly the same name to a directory.
Thoughts So far I have tried to use the' strrep' function failing miserably.
Please Help!!!!

3 Kommentare

Stephen23
Stephen23 am 17 Feb. 2015
Bearbeitet: Stephen23 am 17 Feb. 2015
We can help you achieve this. To do this you should explain the input and output requirements a bit better. We understand MATLAB quite well, so if you tell us a bit more about what you want to achieve, then we can help you with that. Showing us broken code is not so helpful, because it doesn't actually tell us what you want to happen (unless you want to fix that code, of course).
For a start: What is the size of V1 and of what data class is it? Can you please show us exactly the strings (or an example) from the text file? And finally give an example of how you want the output to look like (to be saved in the text file), or explain it a bit more.
EDIT: Thank you for editing your question, it is much nicer!
Stephen23
Stephen23 am 17 Feb. 2015
Bearbeitet: Stephen23 am 17 Feb. 2015
In your example template file, each of '%1', etc, occurs twice. Is this correct? Does each get replaced by the excel-data, or once only taking up the whole space between them?
Actually 4 times; full text is;
if true
icon guess ctot constrain' ! Modern seawater
'h2o' 1 1.000d+0 1.000d+0 ' ' 0 !
'h+' 3 %1 %1 ' ' 0 !pH=8.22
'ca+2' 1 %2 %2 ' ' 0
'mg+2' 1 %3 %3 ' ' 0
'hco3-' 1 %4 %4 ' ' 0
'na+' 1 %5 %5 ' ' 0
'k+' 1 %6 %6 ' ' 0
'so4-2' 1 %7 %7 ' ' 0
'cl-' 1 %8 %8 ' ' 0
'*' 0 0.0 0.0 ' ' 0
1 30.0 !iwtype boundary, temp (C)
icon guess ctot constrain' ! Modern seawater
'h2o' 1 1.000d+0 1.000d+0 ' ' 0 !
'h+' 3 %1 %1 ' ' 0 !pH=8.22
'ca+2' 1 %2 %2 ' ' 0
'mg+2' 1 %3 %3 ' ' 0
'hco3-' 1 %4 %4 ' ' 0
'na+' 1 %5 %5 ' ' 0
'k+' 1 %6 %6 ' ' 0
'so4-2' 1 %7 %7 ' ' 0
'cl-' 1 %8 %8 ' ' 0
end
I just copied and pasted the first half as I thought it wouldn't matter so much.
EDIT: Each gets replaced by the excel data i.e for %1
if true
'h+' 3 3.548E-07 3.548E-07 ' ' 0 !pH=8.22
....
'h+' 3 3.548E-07 3.548E-07 ' ' 0 !pH=8.22
% code
end

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Thorsten
Thorsten am 17 Feb. 2015
A sketch how you could proceed:
1. Read the EXCEL file with xlsread
2. Create long array of char with the desired information
text = 'if true ''GASES'' ... % up the h2o line
Append the rows with the missing data
text = [text
sprintf(' ''h+'' 3 %.3E %.3E '' '' 0 !pH=8.22', 3.548E-07, 3.548E-07)]
3. write the stuff to a file using
save(filename, text, '-ascii')
Please let me know if you got stuck somewhere when implementing along these hints.

6 Kommentare

I think this solution would work if I was to edit a singular line of the text file. Im not sure how this links to the array data, do I replace the , 3.548E-07, 3.548E-07)] with column information? i.e asssuming the array is called EXCELDATA
if true
sprintf(' ''h+'' 3 %.3E %.3E '' '' 0 !pH=8.22', EXCELDATA(:,1), EXCELDATA(:,1))]
end
i.e. doesnt this problem need a strrep function rather than sprint ?
CR = char(10); % carriage return
template = [...
'if true' CR...
' icon guess ctot constrain'' '...
'! Modern seawater' CR...
'''h2o'' 1 1.000d+0 1.000d+0 '' '' 0 !' CR ...
'''h+'' 3 %1 %1 '' '' 0 !pH=8.22' CR ...
'''ca+2'' 1 %2 %2 '' '' 0' CR ...
'''mg+2'' 1 %3 %3 '' '' 0' CR ...
'''hco3-'' 1 %4 %4 '' '' 0' CR ...
'''na+'' 1 %5 %5 '' '' 0' CR ...
'''k+'' 1 %6 %6 '' '' 0' CR ...
'''so4-2'' 1 %7 %7 '' '' 0' CR ...
'''cl-'' 1 %8 %8 '' '' 0' CR ...
'''*'' 0 0.0 0.0 '' '' 0' CR ...
'1 30.0 !iwtype boundary, temp (C)' CR ...
' icon guess ctot constrain'' !' CR ...
'Modern seawater ' CR ...
'''h2o'' 1 1.000d+0 1.000d+0 '' '' 0 ! ' CR ...
'''h+'' 3 %1 %1 '' '' 0 !pH=8.22' CR ...
'''ca+2'' 1 %2 %2 '' '' 0' CR ...
'''mg+2'' 1 %3 %3 '' '' 0' CR ...
'''hco3-'' 1 %4 %4 '' '' 0' CR ...
'''na+'' 1 %5 %5 '' '' 0' CR ...
'''k+'' 1 %6 %6 '' '' 0' CR ...
'''so4-2'' 1 %7 %7 '' '' 0' CR ...
'''cl-'' 1 %8 %8 '' '' 0' CR ...
'end'];
formatstr = '%1.3E';
for i = 1:8
template = strrep(template, sprintf('%%%d', i), formatstr);
end
data8 = [.548E-07 1.183E-01 3.222E-02 1.560E-02 ...
5.771E-01 0.000E+00 2.666E-02 8.113E-01];
% define anonymous function to write the next command as a one-liner
flattenx = @(x) x(:);
filledtemplate = sprintf(template, ...
repmat(flattenx(repmat(data8, [2 1])), [2 1]));
% save filled template
filenumber = 1;
filename = sprintf('myfile%d.txt', filenumber);
fid = fopen(filename, 'w');
fprintf(fid, '%s', filledtemplate);
fclose(fid);
Thankyou so much Thorsten! I edited this and got it it working!!! :)
Ahh no! I thought I had got it working but I realised that it just utilizes the first column of my excel data and misses the other 7 columns. Also it solely writes to the Sol.txt (the output file) file even if I specify a range of file numbers e.g. 1:322. Your assisstance would be most appreciated!!
if true
% code
end
template = fileread('template.txt'); %I compared both this method and writing it out manually as a text string as in your example and they are the same.
formatstr = '%1.3E';
for i = 1:8
template = strrep(template, sprintf('%%%d', i), formatstr);
end
data = xlsread('data.xlsx');
flattenx = @(x) x(:);
filledtemplate = sprintf(template, ...
repmat(flattenx(repmat(data, [2 1])), [2 1]));
filenumber = 1;
filename = sprintf('Sol.txt', filenumber);
fid = fopen(filename, 'w');
fprintf(fid, '%s', filledtemplate);
fclose(fid);
You have to select the column of data that you need in the filledtemplateline:
template = fileread('template.txt');
formatstr = '%1.3E';
% this is just to replace the %1, %2 ...%8 in the template
% with '%1.3E'; it could be done by editing he template you store,
% but I thought it would be nicer to do it in Matlab
for i=1:8
template = strrep(template, sprintf('%%%d', i), formatstr);
end
data = xlsread('data.xlsx');
% this is the main loop that runs trough your data and creates the files
% I dont't know the format of data, so you have to adjust the next two lines accordingly; data_i has to be the 8 values you need to fill the template.
for i = 1:Columns_of_your_data
data_i = data(:,i);
flattenx = @(x) x(:);
filledtemplate = sprintf(template, ...
repmat(flattenx(repmat(data_i, [2 1])), [2 1]));
filename = sprintf('Sol%d.txt', i);
fid = fopen(filename, 'w');
fprintf(fid, '%s', filledtemplate);
fclose(fid);
end
Hope that's now clearer and you can solve your problem.
YESSSSSSSSSSSSSSSS!!!!!!! Thank you!!!!!!!!!!!!!!!!!!!!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Stephen23
Stephen23 am 17 Feb. 2015
Bearbeitet: Stephen23 am 17 Feb. 2015
Here is a pseudocode outline of how you could do this:
data = readExcel;
temp = fileread(filename);
%
xpr = cellstr(reshape(sprintf('(?<=\\s)%%%d(?=\\s)',1:8),[],8).');
%
for k = 1:rows(data)
% extract the data for one instance:
vec = data(k,:);
% convert vec to cell of strings, if required.
% vec should have one string value per cell, size 1x8.
% replace the values in the template:
str = regexprep(temp, xpr, vec);
%
fid = fopen(filename);
fprintf(fid,str);
fclose(fid);
end
You can use regexprep to replace all of those strings simultaneously, without any loops. Because '%1' occurs in other places in the template, I only replace instances of ' %N ', ie with a space character on both sides. You can use fileread to get the whole template as one string.

2 Kommentare

Hillaryfor2016
Hillaryfor2016 am 17 Feb. 2015
Bearbeitet: Hillaryfor2016 am 17 Feb. 2015
Thanks for the help Stephen, your comments have been very helpful! Wish I could accept both answers as I fudged both of the methods together to get it to work.
Glad to help. You can always click on "Votes" :)

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

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

Start Hunting!

Translated by