Clear Filters
Clear Filters

Computations in text files involving both numerical values and text

1 view (last 30 days)
Hi All, I have a text-file involving both text and numerical values. I want to multiple some of the values in the text file with a factor. I.e., I want all values below Res[f(p)] to be multiplied with 1.1. More specific: Value in Row 46 (9.30000E-01) to Row 60 (1.10000E+00) Value in Row 68 (2.40000E-01) to Row 82 (0.70000E+00) Value in Row 141 (4.30100E-01) to Row 155 (4.10100E+00) Value in Row 163 (1.32200E-01) to Row 177 (1.22400E+00) Value in Row 236 (1.30000E-01) to Row 250 (2.10000E+00) Value in Row 258 (2.10000E-01) to Row 272 (0.10000E+00) To all be multiplied with 1.1. Pattern: Start Row 46 and end Row 60. 15 values to be included. 7 Rows break. Start Row 68 and end Row 82. 15 values to be included. 58 Rows break. 15 values to be included. 7 Rows break. 15 values to be included. 58 Rows break. 15 values to be included. 7 Rows break. 15 values to be included. I want to save the file exactly as it was except for the modified values. I have attached the input file (Res.txt) and the wanted output file (OutputRes.txt). Can anyone help me out? Thank you in advance Kind regards,

Accepted Answer

Shrey Tripathi
Shrey Tripathi on 15 Jun 2023
As far as I can understand, you need to just replace the values under the Res[f(p)] column (wherever it appears) with the corresponding value multiplied by 1.1, right?
This can be achieved through the following steps:
  1. Define the input and output file paths
  2. Define the row ranges to extract
  3. Define a function, modify_row, that will extract and modify the appropriate value from a given row
  4. Open the input file for reading
  5. Read the data from the input file into a cell array
  6. For each row range, extract and modify the appropriate value for each row in that range
  7. Replace the original value in each row with the modified value
  8. Open the output file for writing
  9. Write the modified data to the output file
  10. Close both files
The following script performs the above steps:
% Define the input and output file paths
input_file = 'Res.txt';
output_file = 'OutputRes.txt';
% Define the row ranges to extract
row_ranges = {[46, 60], [68, 82], [141, 155], [163, 177], [236, 250], [258, 272]};
% Open the input file for reading
fid_in = fopen(input_file, 'r');
% Read the data from the input file into a cell array
data = textscan(fid_in, '%s', 'Delimiter', '\n');
data = data{1};
% Extract and modify the appropriate value for each row in the specified range
for range_index = 1:length(row_ranges)
% Get the current row range
start_index = row_ranges{range_index}(1);
end_index = row_ranges{range_index}(2);
% Iterate through the each row in the range
for row_index = start_index:end_index
% Extract the appropriate value from the row and modify it
current_row = data{row_index};
value_to_modify = modify_row(current_row);
modified_value = sprintf('%.5E', value_to_modify);
% Replace the original value in the row with the modified value
row_data = strsplit(current_row, ' ');
row_data{4} = modified_value;
modified_row = strjoin(row_data, ' ');
data{row_index} = modified_row;
end
end
% Open the output file for writing
fid_out = fopen(output_file, 'w');
% Write the modified data to the output file
for row_index = 1:length(data)
fprintf(fid_out, '%s\n', data{row_index});
end
% Close both files
fclose(fid_in);
fclose(fid_out);
% Define a function to extract and modify the appropriate value from a given row
function modified_value = modify_row(row)
% Split the row into its whitespace-separated values
row_values = strsplit(row);
% Get the 4th value from the row (corresponding to the "Res[f(p)]" column) and convert it to a double
value_string = row_values{4};
value_double = str2double(value_string);
% Multiply the value by 1.1 and return the result
modified_value = value_double * 1.1;
end
The modify_row function extracts the 4th value from a row (which corresponds to the value under the Res[f(p)] column) and multiplies it by 1.1. It parses the space-separated values in the input row, retrieves its 4th value, converts it to a number (double), and multiplies it by a factor of 1.1. The output modified_value is a scalar double.
  3 Comments
Shrey Tripathi
Shrey Tripathi on 16 Jun 2023
@Askeladden2 to preserve indentation, you'll have to consider the rows that require modification as strings itself, and not break them down into arrays of strings. You can do this by preserving leading whitespaces for the rows into consideration, taking the entire row as string, and modifying the values by overwriting the particular substring needed, since all the rows requiring modofication need to be changed at the same place (more specifically, they only need changes from the columns 45 to 55). You can incorporate these changes through the same script, albeit with a few modifications:
% Define the input and output file paths
input_file = 'Res.txt';
output_file = 'OutputRes.txt';
% Define the row ranges to extract
row_ranges = {[46, 60], [68, 82], [141, 155], [163, 177], [236, 250], [258, 272]};
% Open the input file for reading
fid_in = fopen(input_file, 'r');
% Read the data from the input file into a cell array and preserve leading whitespaces
data = textscan(fid_in, '%s', 'delimiter', '\n', 'whitespace', '');
data = data{1};
% Extract and modify the appropriate value for each row in the specified range
for range_index = 1:length(row_ranges)
% Get the current row range
start_index = row_ranges{range_index}(1);
end_index = row_ranges{range_index}(2);
% Iterate through the each row in the range
for row_index = start_index:end_index
% Extract the appropriate value from the row and modify it
current_row = data{row_index}
value_to_modify = modify_row(current_row)
modified_value = sprintf('%.5E', value_to_modify)
% Replace the original value in the row with the modified value
prev_value = current_row(45:55)
curr_value = modified_value
% Replace the old substring with the new substring
modified_value = strrep(prev_value, prev_value, curr_value)
% Create the new row by concatenating the modified substring to the non-modified parts of the row
modified_row = [current_row(1:44) modified_value current_row(56:end)]
data{row_index} = modified_row
end
end
% Open the output file for writing
fid_out = fopen(output_file, 'w');
% Write the modified data to the output file
for row_index = 1:length(data)
fprintf(fid_out, '%s\n', data{row_index});
end
% Close both files
fclose(fid_in);
fclose(fid_out);
% Define a function to extract and modify the appropriate value from a given row
function modified_value = modify_row(row)
% Split the row into its whitespace-separated values
row_values = strsplit(row);
% Get the 5th value from the row (corresponding to the "Res[f(p)]" column) and convert it to a double
% We take the 5th value because the leading whitespace creates an empty first element
value_string = row_values{5};
value_double = str2double(value_string);
% Multiply the value by 1.1 and return the result
modified_value = value_double * 1.1;
end
The important modifications being:
  1. data = textscan(fid_in, '%s', 'delimiter', '\n', 'whitespace', ''); to preserve leading whitespaces while scanning the input file
  2. Replacing the original value in the row with the modified value by modifying the substring of the string corresponding to the row
This should fix the indentation issue as well.

Sign in to comment.

More Answers (0)

Categories

Find more on Software Development Tools in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!