Вот краткое предложение для алгоритма:
- Откройте файл с помощью
fopen
- Начните чтение строк с
fgetl
, пока не найдете строку, начинающуюся с 'CDS'
. - Сохраняйте строки чтения, пока не получите другую строку, начинающуюся с
'gene'
. - Для всех строк между строкой в (2) и в (3)
- найдите строку между
'/'
и '='
.Это имя поля - найти строку между кавычками.Это значение поля
- Увеличьте счетчик на единицу и начинайте с # 2, пока вы не закончите чтение файла
Эти команды могутбыть полезным:
- Чтобы найти строку, заключенную в определенные символы, используйте, например,
regexp(lineThatHasBeenRead,'/(.+)=','tokens','once')
- Чтобы создать структуру вывода, используйте динамические имена полей, например,
output(ct).(fieldname) = value;
РЕДАКТИРОВАТЬ
Вот код.Я сохранил ваш пример как «test.txt».
% open file
fid = fopen('test.txt');
% parse the file
eof = false;
geneCt = 1;
clear output % you cannot reassign output if it exists with different fieldnames already
output(1:1000) = struct; % you may want to initialize fields here
while ~eof
% read lines till we find one with CDS
foundCDS = false;
while ~foundCDS
currentLine = fgetl(fid);
% check for eof, then CDS. Allow whitespace at the beginning
if currentLine == -1
% end of file
eof = true;
elseif ~isempty(regexp(currentLine,'^\s+CDS','match','once'))
foundCDS = true;
end
end % looking for CDS
if ~eof
% read (and remember) lines till we find 'gene'
collectedLines = cell(1,20); % assume no more than 20 lines pere gene. Row vector for looping below
foundGene = false;
lineCt = 1;
while ~foundGene
currentLine = fgetl(fid);
% check for eof, then gene. Allow whitespace at the beginning
if currentLine == -1;
% end of file - consider all data has been read
eof = true;
foundGene = true;
elseif ~isempty(regexp(currentLine,'^\s+gene','match','once'))
foundGene = true;
else
collectedLines{lineCt} = currentLine;
lineCt = lineCt + 1;
end
end
% loop through collectedLines and assign. Do not loop through the
% gene line
for line = collectedLines(1:lineCt-1)
fieldname = regexp(line{1},'/(.+)=','tokens','once');
value = regexp(line{1},'="?([^"]+)"?$','tokens','once');
% try converting value to number
numValue = str2double(value);
if isfinite(numValue)
value = numValue;
else
value = value{1};
end
output(geneCt).(fieldname{1}) = value;
end
geneCt = geneCt + 1;
end
end % while eof
% cleanup
fclose(fid);
output(geneCt:end) = [];