How to search text file for string, and return the line?

517 ビュー (過去 30 日間)
David Pesetsky
David Pesetsky 2016 年 11 月 6 日
コメント済み: Voss 2023 年 11 月 1 日
Hello,
I need to find where in a file a string occurs, and grab the 5th and 6th values on the same line into 2 variables. Here's a sample of the data:
401 FxTB 2591.1675 15.3213 2569.5085 2619.7012 50.1926 kN
20.840 s 4.080 s
522 103
402 FyTB 0.8813 17.3074 -67.7260 64.5470 132.2730 kN
15.280 s 16.560 s
383 415
I don't know where the FxTB will occur, but I need to store the 2569.5085 and 2619.7012 in two variables. I was using this:
fmt = ['%*f %*s' repmat('%*f',1,2) '%f %f']; % skip snb#/snbName/2numbers, then read 2 values: sensor 401
v = cell2mat(textscan(fid2,fmt,1,'headerlines', 553-1));
...but the line doesn't always occur on line number 553.
Maybe I need to load the whole file into memory...since I do search for about 6 variables per file.

採用された回答

Walter Roberson
Walter Roberson 2016 年 11 月 6 日
loading the file into memory is the easiest way.
If you split the loaded text into lines, then strfind() or regexp() can be used to do the searching.
With strfind() you would
mask = ~cellfun(@isempty, strfind(TextAsCells, 'FxTB'));
the_one_line = TextAsCells(mask);
You can do much the same with regexp()
mask = ~cellfun(@isempty, regexp(TextAsCells, 'FxTB'));
the_one_line = TextAsCells(mask);
However, you can also use regexp() in a way to extract the data values more directly, similar to the below.
If you do not split the loaded text into lines, then regexp() can be used to do the searching.
f56 = regexp(TextAsSingleLine, '(?<=FxTB\s+(\S+\s+){2})\S+\s+\S+','match');
which would return {'2569.5085 2619.7012'}
Or you could use
parts = regexp(TextAsSingleLine, '(?<=FxTB\s+(\S+\s+){2})(?<f5>\S+)\s+(?<f6>\S+)','names')
parts =
struct with fields:
f5: '2569.5085'
f6: '2619.7012'
to get it pre-split.
If it is always the same field numbers then you could use, for example,
parts = regexp(TextAsSingleLine, '(?<varname>(FxTB|FyTB|P7qT)\s+(\S+\s+){2})(?<f5>\S+)\s+(?<f6>\S+)','names')
which should match for variable names FxTB, FyTB, or P7qT with the matched name returned in the varname field of the resulting struct.
  4 件のコメント
David Pesetsky
David Pesetsky 2016 年 11 月 6 日
Ah..this way is spectacularly fast. Then I can use the line number with my old method:
c=textread('my.txt','%s','delimiter','\n');
find(~cellfun(@isempty,strfind(c,'FxTB')))
Please comment.
Walter Roberson
Walter Roberson 2016 年 11 月 6 日
One way:
text = fileread(MyFile);
TextAsCells = regexp(text, '\n', 'split');
Another:
fid = fopen(MyFile, 'rt');
TextAsCells = textscan(fid, '%s', 'Delimiter', '\n');
fclose(fid)
Using regexp is usually fast; it can slow down if there are a lot of false matches that it has to back-track over. Performance can be improved by using line anchors
text = fileread(MyFile);
parts = regexp(text, '(?<=^s+\S+\s+FxTB\s+(\S+\s+){2})(?<f5>\S+)\s+(?<f6>\S+)','names', 'lineanchors')
as then it knows that it does not need to keep looking in the line for occurrences of FxTB

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2016 年 11 月 6 日
A very simple way is to use fgetl() ans strfind():
fid = fopen('fgetl.m');
tline = fgetl(fid);
lineCounter = 1;
while ischar(tline)
disp(tline)
if strcmp(tline, 'FxTB')
break;
end
% Read next line
tline = fgetl(fid);
lineCounter = lineCounter + 1;
end
fclose(fid);
lineCounter is the line number where it occurred. Then you can parse tline to pull out any numbers you want from tline using sscanf() or textscan() or whatever.
  5 件のコメント
taimour sadiq
taimour sadiq 2023 年 11 月 1 日
if contains(tline, 'FxTB', 'IgnoreCase', true)
%% How to replace this 'tline' containing 'FxTB' in file with some string 'Hello'
break;
end
Voss
Voss 2023 年 11 月 1 日
filename_in = "test.txt";
filename_out = "test_modified.txt";
lines = readlines(filename_in);
lines(contains(lines,'fxtb','IgnoreCase',true)) = "Hello";
writelines(lines,filename_out);
% check the input and output files:
type(filename_in);
It was the best of times, it was the blurst of times, it was the age of FxTB, it was the age of foolishness,
type(filename_out);
It was the best of times, it was the blurst of times, Hello it was the age of foolishness,

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCharacters and Strings についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by