Remove rows/text at the bottom of a csv file
古いコメントを表示
Hi,
I have over 2000 csv files and I can read the csv files and store in a cell array. But, all csv files has some text written at the end of the rows (the text is same in all files). How can I delete the text from all files.
Please see the images below. My MATLAB code is shown below.




clear all
cd ('C:\Users\Desktop\')
myFolder = 'C:\Users\Desktop\Q_gte_10';
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
filePattern = fullfile(myFolder, '*.csv');
csvFiles = dir(filePattern);
for k = 1:length(csvFiles)
fid(k) = fopen(fullfile(myFolder,csvFiles(k).name));
out{k} = textscan(fid(k),'%s %s %s %s %*[^\n]','delimiter',',','headerlines',1);
fclose(fid(k));
end
採用された回答
その他の回答 (2 件)
Image Analyst
2015 年 11 月 17 日
I'd simply use fgetl(), strfind() and fprintf(), something like
fid = fopen('foo.csv');
fOutput = fopen('outFoo.csv');
tline = fgetl(fid);
while ischar(tline)
disp(tline)
tline = fgetl(fid);
if ~isempty(strfind(tline, 'DISCLAIMER'))
break;
end
fprintf(fOutput, '%s\n', tline);
end
fclose(fid);
fclose(fOutput);
% If you want back in the same file
delete('foo.csv'); % Delete old/input file
movefile('outFoo.csv', 'foo.csv'); % Rename file.
1 件のコメント
Tunechi
2021 年 5 月 8 日
OK, with the depth of the conversation under the original and that now have access to real data file I'm moving the last comment previous and turning it into "that's my answer and I'm stickin' to it!" :)
You can apply the following to either the cleaned-up versions you attached or to the originals--
fmt='%*s %d %4d-%*2d-%*2d %d %*[^\n]';
for i=1:length(d)
fid=fopen(d(i).name);
c=cell2mat(textscan(fid,fmt,'headerlines',68,'collectoutput',1,'delimiter','\t'));
c(all(c==0,2),:)=[]
[path,name,ext]=fileparts(d(i).name);
csvwrite([fullfile(path,name) '.csv'],c)
fid=fclose(fid);
end
will leave you with a csv file of the same name containing just the above pieces of data for each with the same root name as the original.
With textscan it will abort automagically at the first non-matching line after the data of interest which will clean up the input much more easily than your current gyrations.
The 'collectoutput' argument returns the values in a single cell array and forces an empty cell into all columns; otherwise the first two cell arrays will end up with a zero while the last doesn't owing to the behavior on (the expected) error when hits the trailing text.
cell2mat turns it into an "ordinary" double array instead of cell array so indexing is simpler and since there's no need for mixed types here it's much easier (and faster and less memory intensive to boot). Then the last fixup simply removes that line of all zeros making sure if there are zero flow data values (unlikely, yes, but...) don't remove any actual data by the check the whole row is 0.
NB: The tab delimiter is mandatory to account for the missing/empty fields in some files; otherwise by default it'll fail with one of the characters being read where a numeric value is expected. If you chose, you could use the 'EmptyValue' field and return NaN instead of zero to make it obvious where this is occurring.
NB 2: Ran the above on the full directory to make sure nothing unexpected occurred. Looks ok other than the fact that there are sometimes multiple readings in a given year so that it would appear should keep the month as well to avoid aliasing.
15 件のコメント
dpb
2015 年 11 月 18 日
The fopen/fclose pair didn't get copied for some reason...oh, I did it first with textread which uses the file name then just plunked in the file handle when transmuting to textscan. See updated answer...
dpb
2015 年 11 月 18 日
Oh, in yours you save the file handle in an array on open but used the name w/o the subscript in the textscan call. Don't save all the file handles at once; open one, read it, then close it, reusing the single file handle variable, fid each time.
Damith
2015 年 11 月 19 日
"when I write the output to csv file the numbers are rounded."
Damith
2015 年 11 月 20 日
As noted before, to write cell content of other than all numeric data to a delimited file you have to resort to writing the specific formatting per the cell content in the specific format desired. Recall we demonstrated the subject reference file is tab-delimited during the parsing exercise earlier if you're trying to remain compatible.
I don't have a release here that includes it so can't test but you might 'spearmint w/ the table and see if its exporting facility suits the purpose (and, in fact, you might find it works better overall altho another poster appears to be having issues with writetable but don't know if it's a problem with it itself or operator error).
Damith
2015 年 11 月 20 日
dpb
2015 年 11 月 20 日
"Please see my MATLAB code below."
What about it? Other than I note you are still using and array for fid in the loop over k that's not needed -- you use each file sequentially so there's no need for more than a single variable to hold the file handle. Change references to fid(k) --> fid
After you've got out as you want it, you'll have to loop over each cell and within it loop over the sizes inside to output the content per the defined format. Again, don't forget the '\t' delimiter; you have to write it explicitly; there's no 'delimiter' named parameter for fprintf and friends and as we've already discussed the wrapper routines for delimited file input/output are limited to numeric data only.
dpb
2015 年 11 月 20 日
You know, if the idea is to build a composite file of all the input files but ending up with only the unique values across them for some variable or combination of variables, the simpler approach could be to simply first concatenate all the files without regard to the content other than removing the header and trailer, then open that complete file and do the selection over it.
That would, it would seem, reduce the complexity of doubly-nested cell arrays that you've now got and that are terribly difficult to manipulate.
What, again, is the end objective here and starting from what point?
dpb
2015 年 11 月 20 日
I've had other things had to go do...so you want the records in the "Stations" file matching station IDs in the "US" file. Is any thing in the US file needed to be saved other than simply using to select the station IDs?
And how does this relate to the previous question re: all the myriad of other files?
Damith
2015 年 11 月 20 日
Read both files as cellstring arrays...
U=textread('US_R_05_01_Q.txt','%s','delimiter','\n','whitespace','','headerlines',1);
S=textread('stationList-CurrConditions-9351Stn-2015-06-20.txt','%s','delimiter','\n','whitespace','');
Then locate tabs around second field and parse the field ID from cell array. These locations are the first two tabs per line. Must do this as (I discovered the hard way) that the ID field varies in width significantly from 8 to 14 digits. Thus first return the 2-column array of first and second tab locations in each cellstring that delimits the ID field; the second converts to numeric value...
hdr=S(1); S(1)=[]; % save header line for 'States' file for output later
tab=cellfun(@(x) find(x==9,2),S,'uniform',0);
Ssta=cellfun(@(x,y) str2num(x(y(1)+1:y(2)-1)),S,tab);
tab=cellfun(@(x) find(x==9,2),U,'uniform',0);
Usta=cellfun(@(x,y) str2num(x(y(1)+1:y(2)-1)),U,tab);
[~,istn]=intersect(Ssta,Usta); % find the intersection positions in S
S=S(istn); % and save
fid=fopen('stationsInUS.txt','wt'); % make a new file, name as wish
fprintf(fid,'%s\n',char(hdr)); % write the header line
for i=1:length(S) % have to do each cell string as can't use cell
fprintf(fid,'%s\n',S{i});
end
fid=fclose(fid);
I got
>> length(istn)
ans =
758
>>
intersecting stations. I did it two ways; the above that shows some useful ways to read and manipulate cell arrays and interpret them in memory and by the previously demonstrated technique of parsing the field directly on a read with textread or textscan to make sure had the tab spacing logic correct.
You can use char to convert either U or S above to a 2D character array but in doing so because arrays must be regular the shorter lines are all padded with blanks which doesn't reflect the original file structure exactly. It's also possible to use fread and "suck up" the whole file as a character array, internal control characters and all, including newline but the difficulty in indexing to find the array locations to delete is, while doable, more effort for small files such as these that the time that could be saved by the more efficient read/write operations isn't enough to be worth the coding effort.
Damith
2015 年 12 月 2 日
カテゴリ
ヘルプ センター および File Exchange で Large Files and Big Data についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!







