automatically iterate numbers in a text file

I have a text file that looks like this:
LOAD BOX 1 SUBJ M1_299633_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat1 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 2 SUBJ M2_297928_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat2 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 3 SUBJ M3_299632_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat3 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
LOAD BOX 4 SUBJ M4_297929_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat4 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
LOAD BOX 5 SUBJ F5_299621_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat5 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 6 SUBJ F6_297923_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat6 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 7 SUBJ F7_299626_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat7 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
LOAD BOX 8 SUBJ F8_297924_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat8 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
I want to make a matlab code that will pull a file from a directory, and update the file by iterating by 1 the number after Se on each line (session number), as well as the final number (list number), also iterating by one.
the files are saved under this general format:
SquadNumber_InternalCode_ExperimentName_oldStage_OldSession.txt
the way I envision this is that matlab will pull in the outdated file, see the number 4 as the session number, make the 4 into a 5. it will do the same with the list number. this is the code I have to get some of the information for the creation of the file:
root = 'C:\Users\Administrator\Used_files';
user_input_squad = input('please enter squad number: ');
user_input_experiment = input('please enter experiment name: ');
file = fullfile(root, sprintf('squad%s_1910_%s_St6_Se4.txt', user_input_squad, user_input_experiment));
Used_file = importdata(file);
I want to make a code that will update all instances of Se4 in the file to Se5, every day, as well as update the name of the file to Se5.
I also want the last number to be iteratede by one, but in this case only go up to 5, and then start back at 1.
thanks for the help, I appreciate it.

 Akzeptierte Antwort

Guillaume
Guillaume am 12 Dez. 2019

0 Stimmen

root = 'C:\Users\Administrator\Used_files';
user_input_squad = input('please enter squad number: ');
user_input_experiment = input('please enter experiment name: ');
file = fullfile(root, sprintf('squad%s_1910_%s_St6_Se4.txt', user_input_squad, user_input_experiment));
%get raw content of file as text
filetext = fileread(file);
%increase number after Se by 1, and increase last number modulo 5.
newtext = regexprep(filetext, '(?<=Se)(\d+)(.*)(\d+)$', ...
'${num2str(str2double($1)+1)}$2${num2str(mod(str2double($3), 5)+1)}', ...
'lineanchors', 'dotexceptnewline');
%generate new file name
newfile = fullfile(root, sprintf('squad%s_1910_%s_St6_Se4.txt', user_input_squad+1, user_input_experiment));
%and write new text
fid = fopen(newfile, 'w');
fwrite(fid, newtext);
fclose(fid);

8 Kommentare

avram alter
avram alter am 12 Dez. 2019
Bearbeitet: avram alter am 12 Dez. 2019
hello, unfortunately it doesn't seem to do anything, it saves a new file under the new name, but nothing else is updated, the code stays the same. I'll show you:
LOAD BOX 1 SUBJ M1_299633_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat1 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 2 SUBJ M2_297928_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat2 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 3 SUBJ M3_299632_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat3 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
LOAD BOX 4 SUBJ M4_297929_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat4 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
LOAD BOX 5 SUBJ F5_299621_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat5 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 6 SUBJ F6_297923_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat6 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 3
LOAD BOX 7 SUBJ F7_299626_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se4_Rat7 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
LOAD BOX 8 SUBJ F8_297924_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se4_Rat8 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 3
this is the old file, I want the new file to look like this, with Se4 turning to Se5. Or if the user called file was Se5, turning it into Se6, etc. the last number will only count to 5, and then go back to 1:
LOAD BOX 1 SUBJ M1_299633_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se5_Rat1 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 4
LOAD BOX 2 SUBJ M2_297928_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se5_Rat2 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 4
LOAD BOX 3 SUBJ M3_299632_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se5_Rat3 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 4
LOAD BOX 4 SUBJ M4_297929_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se5_Rat4 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 4
LOAD BOX 5 SUBJ F5_299621_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se5_Rat5 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 4
LOAD BOX 6 SUBJ F6_297923_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se5_Rat6 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbi 4
LOAD BOX 7 SUBJ F7_299626_D295158_JUN19@1910_Aut_ERROR2 EXPT St6_Se5_Rat7 GROUP 1 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 4
LOAD BOX 8 SUBJ F8_297924_D294277_APR19@1910_Aut_ERROR2 EXPT St6_Se5_Rat8 GROUP 2 PROGRAM 1908_SIP_EPHYS_ERROR2_St3_TrainWZ_Cbii 4
with the last number updating by one and wrapping back to one after 5, and the number after Se to increase by one. It could be I didn't make myself clear, so I'll try to explain.
the user inputs are for the old file, bringing it in. I then want the code to run, updating the old file, and saving it as a new. I apologize if I was not clear
Guillaume
Guillaume am 13 Dez. 2019
Bearbeitet: Guillaume am 13 Dez. 2019
Please attach an actual text file then so that we know what actual encoding and line ending your file use. My code works fine with the attached file which is just a paste of what you wrote in your question.
edit: just thought that if your file uses windows line endings the regular expression won't work properly. It would still increment the Se of the first line and the last number of the last line and you said that nothing change so this is probably not the issue.
Anyway, to work with any sort of line ending replace the regular expression with:
newtext = regexprep(filetext, '(?<=Se)(\d+)(.*)(\d+)(?=[\n\r]|$)', ...
'${num2str(str2double($1)+1)}$2${num2str(mod(str2double($3), 5)+1)}', ...
'dotexceptnewline');
avram alter
avram alter am 18 Dez. 2019
Bearbeitet: avram alter am 18 Dez. 2019
I apologize that this took so long. I have included a link to the file, as it cannot be uploaded directly here. note that it is a .mac file. this is not for apple electronics, it is a proprietary type of file used with med-pc software. that may be the issue here. I beleive the file can be opened in notepad, or notepad++. The file is named squad2_1910_EXP1_St3_Se4. https://github.com/Rambunctiouslad/Rat_Tracking
Notepad++ shows it is UTF-8 encoding, and I had the newlines made with \n and MATLAB's compose() function.
Testig it with a .txt file yielded the same results. I have included one of those here as well.
For this sort of questions always provide an example file as this helps avoiding this kind of problem. You can indeed rename your sample files to .txt to post the file, the extension is irrelevant.
The simple reason why my regular expression did not work is that the number at the end of the line is not in fact at the end of the line. It's always followed by a space which wasn't present in any of the examples you wrote.
New regular expression which allows for spaces (and spaces only) at the end of the line:
newtext = regexprep(filetext, '(?<=Se)(\d+)(.*)(\d+)(?= *([\n\r]|$))', ...
'${num2str(str2double($1)+1)}$2${num2str(mod(str2double($3), 5)+1)}', ...
'dotexceptnewline')
Description of the regular expression:
  • Match must be preceded by Se. Then match must consist of
  • First token: one or more digits, followed by
  • Second token: 0 or more of anything except new line, followed by
  • Third token: one or more of digits
  • Match must be followed by 0 or more spaces, followed by a new line (\n or \r) or the end of the string)
Description of the replacement expression
  • convert first token to double, add one, convert back to char
  • second token as is
  • convert third token to double, take the mod modulo 5, add 1, convert back to char
avram alter
avram alter am 20 Dez. 2019
hey, that works really well, thank you. I have been reading up on the regexprep function, and I only understand a few things, in the code, like ?<+Se, or the dotexceptnewline. If you have time, could you break it down for me? I would really appreciate it.
avram alter
avram alter am 23 Dez. 2019
Bearbeitet: avram alter am 23 Dez. 2019
I am getting the error
filename must be a string or scalar vector
I assume that is because I added the extension to the name of the file. I have added my full code here, please note I am using the earlier version of hte code, having rid myself of those spaces at the end of the line.
root = 'C:\Users\Administrator\Dropbox (********)\******** Team Folder\Matlab\RFID chip reader\Completed_Macros';
user_input_squad = input('please enter squad number: ', 's');
user_input_experiment = input('please enter experiment name: ', 's');
user_input_stage = input('please enter stage: ', 's');
user_input_session = input('Please enter session: ', 's');
file = fullfile(root, sprintf('squad%s_1910_EXP%s_St%s_Se%s.mac', user_input_squad, user_input_experiment, user_input_stage, user_input_session));
file = importdata(file);
filetext = fileread(file);
%increase number after Se by 1, and increase last number modulo 5.
newtext = regexprep(filetext, '(?<=Se)(\d+)(.*)(\d+)$', ...
'${num2str(str2double($1)+1)}$2${num2str(mod(str2double($3), 5)+1)}', ...
'lineanchors', 'dotexceptnewline');
%generate new file name
newfile = fullfile(root, sprintf('squad%s_1910_EXP%s_St%s_Se%s', user_input_squad, user_input_experiment, user_input_stage, user_input_session+1));
%and write new text
fid = fopen(newfile, 'w');
fwrite(fid, newtext);
fclose(fid);using
using breakpoints after importfile shows
file is 1x 1 struct with 2 fields
data [4;4;4;4;4;4;4;4]
textdata 8x11 cell
opening the textdata matrix reveals the file, but it is missing the list number. do you know what is causing this?
"do you know what is causing this?"
Nothing to do with my code. It's your overloading of the variable file, first used to store the filename, then used to store the content of the file that you imported with importdata. It's your addition of the line:
file = importdata(file);
As for the regex:
  • (?<=Se) means that a match must be preceded by Se
  • (\d+) is the first token captured. It matches 1 or more digits. Meant to match the number after Se
  • (.*) is the 2nd token captured. It matches anything except a new line. Meant to match the rest of the line before:
  • (\d+) third token captured. It matches 1 or more digits. Meant to match the number at the end of the line because:
  • (?= *([\n\r]|$) match must be followed by any number of space (the space followed by *) followed by either \n or \r (windows/linux newlines) or the end of the text (for the last line).
avram alter
avram alter am 24 Dez. 2019
I'm not sure when I included that line. Possibly when I ran it on a new system. Either way, got it up aan running without a hitch, thank you for all the help. Fantastic explanation as well.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Creating, Deleting, and Querying Graphics Objects finden Sie in Hilfe-Center und File Exchange

Produkte

Version

R2019b

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by