Reputation: 165
I'm trying to read a .log file and get information that will later be used to create a graph.
%Open text file
fileID = fopen('file.log');
text = textscan(fileID, '%s', 'delimiter','\n','whitespace','');
json_text=cellfun(@(x) x(53:end-1),text, 'UniformOutput',false);
%Decode in json
data=cellfun(@jsondecode,json_text,'UniformOutput',false);
I'm getting the following error:
Error using jsondecode JSON text must be a character vector or a scalar non-missing string.
To me, it seemed like a straightforward problem to solve, but I tried googleing it and I can't find any solution.
I have tested if the first three commands are working (e.g. without decoding to json part) and it works. So the problem is when I try to decode the data to json.
Any hints what the problem could be?
Below is a sample line from the .log file:
123456.99 :: working completed: result=0 , data ="{"day":"monday", "breakfast":"sandwich"}"
Upvotes: 0
Views: 1350
Reputation: 99
I think 2018b introduced a bug in jsondecode. A test file containing only this text (taken straight from the documentation of jsondecode):
{"IDs":[116,943,234,38793]}
(with a linefeed at the end of the file) is correctly decoded by the jsondecode that came with Matlab 2018a, but the version in 2018b prints the error
Error using jsondecode JSON text must be a character vector or a scalar non-missing string.
Upvotes: 1
Reputation: 26084
The code is correct, just minor changes need to be made.
In the cellfun call, you should change the character vector range to include the opening { bracket. This does assume that the location of the bracket is fixed across your text file.
You should also expand text when calling the cellfun function.
Sample log file:
123456.99 :: working completed: result=0 , data ="{"day":"monday", "breakfast":"sandwich"}"
123456.99 :: working completed: result=0 , data ="{"day":"tuesday", "breakfast":"bread"}"
Code snippet:
% Open text file.
fileID = fopen('file.log');
text = textscan(fileID, '%s', 'delimiter','\n','whitespace','');
json_text=cellfun(@(x) x(51:end-1),text{:}, 'UniformOutput',false);
% Decode in json.
data=cellfun(@jsondecode,json_text,'UniformOutput',false);
% Close text file.
fclose(fileID);
Result:
>> data{:}
ans =
struct with fields:
day: 'monday'
breakfast: 'sandwich'
ans =
struct with fields:
day: 'tuesday'
breakfast: 'bread'
Upvotes: 1
Reputation: 24169
I can't reproduce your problem:
json_text = {'{"day":"monday", "breakfast":"sandwich"}'}
data = cellfun(@jsondecode, json_text,'UniformOutput', false);
%{
>> data{1}
ans =
struct with fields:
day: 'monday'
breakfast: 'sandwich'
%}
But I did run into another problems related mainly to the cutting of the string at a predefined position 53
. It's much better to cut the log lines after the string data =
instead of relying on a predefined position (which might change due to unforeseen variations in the structure of the log file).
Since you're using the latest MATLAB version, you can save yourself some effort by working with String arrays:
strLog = string(text); % This turns the cell array into a vector of string objects
res = split(strLog, "data ="); % You should end up with two columns for non-scalar input.
json_str = res(:, 2);
% < You can take it from here >
Upvotes: 1