I am looking for MATLAB code that does some routine (updates a file.m), if file.csv is edited more recently than file.m.
Something that should look like:
% Write time extraction
tempC = GetFileTime('file.csv', [], 'Write');
tempdateC = tempC.date
tempM = GetFileTime('file.m', [], 'Write');
tempdateM = tempM.date
% Write time comparison
if numel(dir('file.m')) == 0 || tempdateC >= tempdateM
matDef = regexprep(fileread('file.csv'), '(\r\n|\r|\n)', ';\n');
f = fopen('file.m', 'w');
fwrite(f, ['Variable = [' matDef(1:end) '];']);
fclose(f);
end
The lines for timestamp extraction seem to be incorrect MATLAB code. The rest works (Evaluate variables in external file strings).
You can extract the modification time of a file using MATLAB's dir command. Something like:
function modTime = GetFileTime(fileName)
listing = dir(fileName);
% check we got a single entry corresponding to the file
assert(numel(listing) == 1, 'No such file: %s', fileName);
modTime = listing.datenum;
end
Note that the output is in MATLAB's datenum serial date format.
Related
At first, I would like to say that this is not a duplicate of this: Reading CSV files with MATLAB?
In my script, I am trying to read a CSV file (sensor data). It is of the format:
2015-10-08 01:00:00.000,-0.762,-0.68,-0.234
2015-10-08 01:00:00.013,-0.762,-0.676,-0.234
2015-10-08 01:00:00.025,-0.762,-0.672,-0.234
2015-10-08 01:00:00.038,-0.762,-0.672,-0.23
and suddenly I get this error:
Error using dlmread (line 147)
Mismatch between file and format character vector.
Trouble reading 'Numeric' field from file (row number 1, field number 1) ==>
,-0.02,-0.004,1.004\n
Error in csvread (line 48)
m=dlmread(filename, ',', r, c);
Error in getAvgData (line 17)
rawData = csvread([filePath, '/', fileList.name]);
Error in precomputeProcess (line 31)
getAvgData;
This code used to work well without this error and this is the first time I am seeing this. I am not sure if textScan would be of any help. here is my code snippet:
for k = 1:length(hourSampleRateList)
hourSampleRate = hourSampleRateList(k);
disp(['Start at sampling rate: ', num2str(hourSampleRate)]);
for hour = startHour:endHour
hourStr = num2str(hour,'%02i');
filePath = fullfile(pwd, username, 'MasterSynced', yearStr, monthStr,dayStr,hourStr);
fileList = dir([filePath, '/RawDataFloat*.csv']);
if (isempty(fileList))
continue;
end
rawData = csvread([filePath, '/', fileList.name]);
avgData = zeros(ceil(length(rawData)/hourSampleRate), 4);
j = 1;
for i = 1:hourSampleRate:length(rawData)-1;
avgData(j, :) = mean(rawData(i:i+hourSampleRate-1, :));
j = j + 1;
end
filePath = fullfile(pwd, username, 'MasterSynced', yearStr, monthStr,dayStr,hourStr);
myPath = [filePath, '\Avg', num2str(hourSampleRate, '%03i'), '-', fileList.name];
if exist(myPath, 'file') == 2
delete(myPath);
end
dlmwrite(myPath,avgData,'delimiter',',','precision','%.3f');
disp(['Day-Hour(', dayStr, '-', hourStr, '): completed.']);
end
end
Any help or info would be helpful.
M = csvread(filename) reads a comma-separated value (CSV) formatted
file into array M. The file must contain only numeric values.
Your first column is a date, not a numerical value.
M = csvread(filename,R1,C1) reads data from the file starting at row
offset R1 and column offset C1.
So you may skip the first column by using rawData = csvread([filePath, '/', fileList.name],0,1);
Also if your version is < 2016b, this MATLAB Answer suggests to use textscan instead, with 'HeaderLines',8 and appropriate format discriptor, 'Delimiter', and if necessary, 'EndOfLine' declarations.
I have a text file with data structure like this
30,311.263671875,158.188034058,20.6887207031,17.4877929688,0.000297248129755,aeroplane
30,350.668334961,177.547393799,19.1939697266,18.3677368164,0.00026999923648,aeroplane
30,367.98135376,192.697219849,16.7747192383,23.0987548828,0.000186387239864,aeroplane
30,173.569274902,151.629364014,38.0069885254,37.5704650879,0.000172595537151,aeroplane
30,553.904602051,309.903320312,660.893981934,393.194030762,5.19620243722e-05,aeroplane
30,294.739196777,156.249740601,16.3522338867,19.8487548828,1.7795707663e-05,aeroplane
30,34.1946258545,63.4127349854,475.104492188,318.754821777,6.71026540999e-06,aeroplane
30,748.506652832,0.350944519043,59.9415283203,28.3256549835,3.52978979379e-06,aeroplane
30,498.747009277,14.3766479492,717.006652832,324.668731689,1.61551643174e-06,aeroplane
30,81.6389465332,498.784301758,430.23046875,210.294677734,4.16855394647e-07,aeroplane
30,251.932098389,216.641052246,19.8385009766,20.7131652832,3.52147743106,bicycle
30,237.536972046,226.656692505,24.0902862549,15.7586669922,1.8601918593,bicycle
30,529.673400879,322.511322021,25.1921386719,21.6920166016,0.751171214506,bicycle
30,255.900146484,196.583847046,17.1589355469,27.4430847168,0.268321367912,bicycle
30,177.663650513,114.458488464,18.7516174316,16.6759414673,0.233057001606,bicycle
30,436.679382324,273.383331299,17.4342041016,19.6081542969,0.128449092153,bicycle
I want to index those file with a label file.and the result will be something like this.
60,509.277435303,284.482452393,26.1684875488,31.7470092773,0.00807665128377,15
60,187.909835815,170.448471069,40.0388793945,58.8763122559,0.00763951029512,15
60,254.447280884,175.946624756,18.7212677002,21.9440612793,0.00442053096776,15
However there might be some class that is not in label class and I need to filter those line out so I can use load() to load in.(you can't have char inside that text file and execute load().
here is my implement:
function test(vName,meta)
f_dt = fopen([vName '.txt'],'r');
f_indexed = fopen([vName '_indexed.txt'], 'w');
lbls = loadlbl()
count = 1;
while(true),
if(f_dt == -1),
break;
end
dt = fgets(f_dt);
if(dt == -1),
break
else
dt_cls = strsplit(dt,','){7};
dt_cls = regexprep(dt_cls, '\s+', '');
cls_idx = find(strcmp(lbls,dt_cls));
if(~isempty(cls_idx))
dt = strrep(dt,dt_cls,int2str(cls_idx));
fprintf(f_indexed,dt);
end
end
end
fclose(f_indexed);
if(f_dt ~= -1),
fclose(f_dt);
end
end
However it work very very slow because the text file contains 100 thousand of lines. Is it anyway that I could do this task smarter and faster?
You may use textscan, and get the indices/ line numbers of the labels you want. After knowing the line numbers, you can extract what you want.
fid = fopen('data.txt') ;
S = textscan(fid,'%s','delimiter','\n') ;
S = S{1} ;
fclose(fid) ;
%% get bicycle lines
idx = strfind(S, 'bicycle');
idx = find(not(cellfun('isempty', idx)));
S_bicycle = S(idx)
%% write this to text file
fid2 = fopen('text.txt','wt') ;
fprintf(fid2,'%s\n',S_bicycle{:});
fclose(fid2) ;
From S_bicycle, you can extract your numbers.
I would like to plot a number of 3D graphs from different data files. For example I am using
fid = fopen('SS 1.dat','r');
to read the first file and then plot a graph. How to set the program to change the name to 'SS 2.dat' automatically? Also for the tenth file the name becomes 'SS 10.dat' which has one space less (i.e.only two space between SS and 10) then the first to ninth files. How to set the program to adjust for that? Thank you.
Use dir:
filenames = dir('*.dat'); %//gets all files ending on .dat in the pwd
for ii =1:length(filenames)
fopen(filenames(ii),'r');
%//Read all your things and store them here
end
The beauty of dir as opposed to the other solutions here is that you can get the contents of the pwd (present working directory) in one single line, regardless of how you called your files. This makes for easier loading of files, since you do not have any hassle with dynamic file names.
The following code displays a lazy way to print the names from 1 to 999 that you mentioned:
for ii=1:999
ns = numel(num2str(ii));
switch ns
case 1
fname = ['ss ' num2str(ii) '.dat'];
case 2
fname = ['ss ' num2str(ii) '.dat'];
case 3
fname = ['ss ' num2str(ii) '.dat'];
end
end
Another way:
is to use the backslash character in the formatting of the filename as follows:
fstr = 'ss ';
for ii = 1:999
ns = numel(num2str(ii));
for jj = 1:ns-1
fstr = [fstr '\b'];
end
ffstr = sprintf(fstr);
fname = [ffstr num2str(ii) '.dat'];
disp(fname);
end
there are many better ways to do this though
prefix = 'SS';
for n = 1:10
if n == 10
filename = [prefix ' ' num2str(n) '.dat'];
else
filename = [prefix ' ' num2str(n) '.dat'];
end
fid = fopen(filename, 'r');
...
end
I want to acces a .csv file, look for empty data blocks and store all of the lines that have no empty data blocks.
This is my code:
filename = 'C:\Users\try.csv';
file1 = fopen(filename); %Acces file with empty data blocks
filename2 = 'C:\Users\try_corrected.csv';
file2 = fopen(filename2); %Acces destination file
tline = fgets(file1); %Read the first line of file1
while ischar(tline)
detected = false;
[r,s] = size(tline); %Determine the lengt of the textline for the for-loop
for(i=1: 1: s)
if( (tline(i)==',' && tline(i+1) ==',') || tline(1)==',' || tline(s-2)==',' )
detected = true %Line should not be printed in destination file
break;
end
end
if detected == false
fprintf(file2,'%s\n',tline);
end
tline = fgets(file1);
end
type 'C:\Users\try_corrected.csv'
fclose(file2);
textdata = textscan(file1, '%s %f %f %f %s %f %f %f %s %f %s','HeaderLines', 1,'Delimiter',',');
fclose(file1);
If I do the "type" command, I should see all the printed strings which is not the case.
Am I using fprintf wrong? I know there is a command called csvwrite but I thought this could work too?
First, when you open your destination file you need to open it for writing. Without a second parameter fopen will open for read access. If your destination file did not exist it would return you a -1 file handle.
Use instead:
fopen(filename2,'w')
Here is a simplified version of your code including that amendment:
filename = 'c:\try.csv';
fid_in = fopen(filename,'r'); %Access file with empty data blocks
filename2 = 'C:\try_corrected.csv';
fid_out = fopen(filename2,'w'); %Access destination file
while (~feof(fid_in))
str=fgets(fid_in);
if (~doublecommas(str))
fprintf(fid_out,'%s',str);
end
end
fclose(fid_in);
fclose(fid_out);
type(filename2)
This uses a different method to detect double presence of commas in the CSV line:
function flag=doublecommas(str)
flag=false; % flag = result returned,
% true if empty CSV fields present in line
if (ischar(str) && length(str)>0)
for cindex=1:length(str)-1
if strcmp(str(cindex:(cindex+1)),',,')
flag=true; break;
end
end
end
return;
My code has 2 parts. First part is an automatic file opening programmed like this :
fichierref = 'H:\MATLAB\Archive_08112012';
files = dir(fullfile(fichierref, '*.txt'));
numberOfFiles = numel(files);
delimiterIn = ' ';
headerlinesIn = 11;
for d = 1:numberOfFiles
filenames(d) = cellstr(files(d).name);
end
for i=1:numberOfFiles
data = importdata(fullfile(fichierref,filenames{i}),delimiterIn,headerlinesIn);
end
Later on, I want the user to select his files for analysis. There's a problem with this though. I typed the lines as follow :
reference = warndlg('Choose the files from which you want to know the magnetic field');
uiwait(reference);
filenames = cellstr(uigetfile('./*.txt','MultiSelect', 'on'));
numberOfFiles = numel(filenames);
delimiterIn = ' ';
headerlinesIn = 11;
It's giving me the following error, after I press OK on the prompt:
Error using cellstr (line 34)
Input must be a string.
Error in FreqVSChampB_no_spec (line 128)
filenames = cellstr(uigetfile('./*.txt','MultiSelect', 'on'));
Anyone has an idea why it's doing that?
You do not need the cellstr command for the output of uigetfile in 'MultiSelect' mode: the output is already in a cellarray form (see doc of uigetfile).