Replace strings with a different string and save the data
3 views (last 30 days)
Show older comments
I have a file for atomic coordinates, where I wanted to replace the 'c' with a certain pertange of maerials 'Fe', 'Al', 'Au'. The column C needs to be replaced with 40% Fe, 30% Al and 30% Au. Nothing else changes. The rest of the files stays same. I also plan to extend this to more elements lets say, Fe, Al, Ni, Cu, Zr all 20% each. I have attached a sample file. Below is a exceprt from the file. I will really appreciate any suggestions.
168
generated by VMD
C 0.000000 0.000000 0.000000
C -0.866025 0.500000 0.000000
C -0.866025 1.500000 0.000000
C 0.000000 2.000000 0.000000
C 1.732051 0.000000 0.000000
C 0.866025 0.500000 0.000000
C 0.866025 1.500000 0.000000
C 1.732051 2.000000 0.000000
C 3.464102 0.000000 0.000000
C 2.598076 0.500000 0.000000
0 Comments
Answers (2)
VBBV
on 9 Dec 2023
Edited: VBBV
on 9 Dec 2023
D = readtable('data.txt');
C = char(['40% Fe';'30% Al']) % e.g. element data to be filled in 1st column
D.(1) = repmat(C,168/2,1) % replace 1st column of the table with element data
2 Comments
VBBV
on 9 Dec 2023
You can rpleace the 1st column of the datatable with percentage of elements you want as vector shown above
Voss
on 21 Dec 2023
I assume that you want to replace the C's with the specified elements (e.g., Fe, Al, Ni) at random according to the specified proportions (e.g., 40, 30, 30).
% name of the original file:
filename = 'graphene.txt';
% name of the new file that will be created, with the new elements in the
% specified (approximate) proportions:
new_filename = 'graphene_modified.txt';
% elements to replace the "C"s with:
elements = ["Fe","Al","Ni"];
% (approximate) proportion of each element to use:
proportions = [40,30,30];
% show the original file's contents, for reference:
dbtype(filename)
% read the file into string array L, each element of which is a line of
% text from the file:
L = readlines(filename);
% fidx: indices of the lines that start with " C":
fidx = find(startsWith(L," C"));
% total number of lines that will be altered:
N_lines = numel(fidx);
% number of lines that will be altered, for each element:
N = round(proportions/sum(proportions)*N_lines);
% enforce that sum(N) == N_lines:
N(end) = N_lines-sum(N(1:end-1));
% permute fidx to get a random replacement order:
fidx = fidx(randperm(N_lines));
% get the start and end index (in fidx) for each element:
temp = cumsum([0 N]);
s_idx = temp(1:end-1)+1;
e_idx = temp(2:end);
% loop over elements and replace the "C"s:
for ii = 1:numel(elements)
% indices of the random lines of text that will be changed to
% element(ii):
idx = fidx(s_idx(ii):e_idx(ii));
% replace "C" with element(ii) in those lines:
L(idx) = replace(L(idx),"C",elements(ii));
end
% write the result to a new file:
writelines(L,new_filename)
% verification: check the new file's contents:
dbtype(new_filename)
% verification: read the new file and verify that each element starts the
% expected number of lines:
new_L = readlines(new_filename);
for ii = 1:numel(elements)
assert(nnz(startsWith(new_L," "+elements(ii))) == N(ii), ...
sprintf('Unexpected number of "%s" lines',elements(ii)));
end
0 Comments
See Also
Categories
Find more on Low-Level File I/O in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!