Get the names of all the files in a folder as a cell with readdir()
:
filenames = readdir('Input')
## filenames =
## {
## [1,1] = .
## [2,1] = ..
## [3,1] = example_csv.csv
## [4,1] = example_csv.txt
## [5,1] = example_image_1.png
## [6,1] = example_image_2.png
## [7,1] = example_image_3.png
## [8,1] = example_matrix.mat
## [9,1] = example_ods.ods
## [10,1] = example_text.txt
## [11,1] = example_xls.xls
## [12,1] = example_xlsx.xlsx
## }
As you can see, the first two ‘files’ are the special .
and ..
objects which refer to the current and parent directories, respectively.
We can loop over all the files in the chosen folder using a for
loop that runs from 1 until the it hits the number of files that were found:
numel()
function to get this value - it returns the number of elements in a cellregexp()
function to find the special .
and ..
values and skip them with continue
% List the filenames in a directory
filenames = readdir('Input');
% Iterate through the filenames
for i = 1:numel(filenames)
filename = filenames{i, 1};
% Skip the '.' and '..' directories
if (regexp(filename, "^\\.\\.?$"))
continue;
endif
filename
endfor
## filename = example_csv.csv
## filename = example_csv.txt
## filename = example_image_1.png
## filename = example_image_2.png
## filename = example_image_3.png
## filename = example_matrix.mat
## filename = example_ods.ods
## filename = example_text.txt
## filename = example_xls.xls
## filename = example_xlsx.xlsx
Sometimes we only want to work with one file type, eg if we are analysing images we wouldn’t want our script to import .txt
files. The fileparts()
function is useful for this because it splits a file name up into its directory, name, and extension:
[dir, name, ext] = fileparts(filename)
Note that Octave does not check to see if filename
actually exists when this function is run, it just treats it as an arbitrary string.
The above can be used in our loop to find and then skip files that do not have the .png
extension:
% List the filenames in a directory
filenames = readdir('Input');
% Iterate through the filenames
for i = 1:numel(filenames)
filename = filenames{i, 1};
% Skip the '.' and '..' directories
if (regexp(filename, "^\\.\\.?$"))
continue;
endif
% Skip files that are not images
[dir, name, ext] = fileparts(filename);
if (~strcmp(ext, '.png'))
continue;
endif
filename
endfor
## filename = example_image_1.png
## filename = example_image_2.png
## filename = example_image_3.png
Once we’ve got each of the filenames we want in turn, we can do something with them. As an example, we can import each of the images, turn them completely black and then export them to a different folder.
fullfile()
to create the full filepaths to the imagesimread()
to read the images into Octaveimwrite()
to write the images back to your computer% List the filenames in a directory
filenames = readdir('Input');
% Iterate through the filenames
for i = 1:numel(filenames)
filename = filenames{i, 1};
% Skip the '.' and '..' directories
if (regexp(filename, "^\\.\\.?$"))
continue;
endif
% Skip files that are not images
[dir, name, ext] = fileparts(filename);
if (~strcmp(ext, '.png'))
continue;
endif
% Load next file
filepath = fullfile('Input', filename);
image = imread(filepath);
% Make it completely black
image = image.*0;
% Export
filepath = fullfile('Output', filename);
imwrite(image, filepath)
endfor
A ‘diary’ stores everything that is shown on the terminal screen. This then gets saved into a plain text file called diary
in the working directory. If a diary file already exists, this will append to that file.
diary on
will start this recordingdiary off
will stop this recordingdiary
will toggle recordingdiary {filename}
can be used to change the name of the diary file
diary([datestr(now, 'yyyy-mm-dd'), ' diary'])
will prepend the current date to the filename% This will save everything that is printed on the terminal into a file called
% "diary" with today's date at the front. If this file already exists it will
% be appended to, otherwise it will be created.
diary([datestr(now, 'yyyy-mm-dd'), ' diary'])
for i = 1:5
i
endfor
## i = 1
## i = 2
## i = 3
## i = 4
## i = 5
In the diary file:
i = 1
i = 2
i = 3
i = 4
i = 5
The fopen()
, fdisp()
and fclose()
functions can be used to open files, display strings in them and then close them:
filepath = 'Output/example_text.txt';
fid = fopen(filepath, 'w');
max_heart_rate = 191;
resting_heart_rate = 50;
reserve_heart_rate = max_heart_rate - resting_heart_rate;
x = [
'Maximum heart rate: ', num2str(max_heart_rate), ' BPM';
'Resting heart rate: ', num2str(resting_heart_rate), ' BPM';
'Reserve heart rate: ', num2str(reserve_heart_rate), ' BPM';
];
fdisp(fid, x)
fclose (fid);
In example_text.txt
we now have:
Maximum heart rate: 191 BPM
Resting heart rate: 50 BPM
Reserve heart rate: 141 BPM
Given a file called example_text.txt
inside a folder Input
that contains the following:
1
2
3
4
5
We can search for it, find it and import these numbers using the following:
format compact
% List the filenames in a directory
filenames = readdir('Input');
% Iterate through the filenames
for i = 1:numel(filenames)
filename = filenames{i, 1};
% Skip the '.' and '..' directories
if (regexp(filename, "^\\.\\.?$"))
continue;
endif
% Skip files that don't have the .txt extension
[dir, name, ext] = fileparts(filename);
if (~strcmp(ext, '.txt'))
continue;
endif
% Import as a cell
filepath = fullfile('Input', filename);
fid = fopen(filepath, 'r');
data_cell = textscan(fid, '%s');
% Import as a matrix
filepath = fullfile('Input', filename);
data_mat = csvread(filepath);
endfor
data_cell
data_mat
## data_cell =
## {
## [1,1] =
## {
## [1,1] = 1
## [2,1] = 2
## [3,1] = 3
## [4,1] = 4
## [5,1] = 5
## }
## }
##
## data_mat =
## 1
## 2
## 3
## 4
## 5
We can then write this data to MATLAB files using the following:
save('Output/example_cell.mat', 'example_cell')
save('Output/example_matrix.mat', 'example_matrix')
Working with data in MATLAB files (with the .mat
extension) is a lot easier and, in general, recommended. We can load one as follows:
load('Input/example_matrix.mat')
This particular file contains data called example_data
, and we can use this inside our script:
load('Input/example_matrix.mat')
example_data
## example_data =
##
## 1
## 2
## 3
## 4
## 5
Once we’re done, we can save it as a MATLAB file as follows:
save('Output/example_matrix.mat', 'example_data')
Note that if the filenames do not have spaces in them we can omit the brackets and quotation marks:
% Create a matrix
my_matrix = [1 2; 3 4];
% Save matrix to MATLAB file
save example_matrix.mat my_matrix
% Load matrix from MATLAB file
load example_matrix.mat
% View
my_matrix
## my_matrix =
##
## 1 2
## 3 4
These can be created, saved and loaded in a similar way to matrices:
% Create a struct
my_struct.rank = 1;
my_struct.player = 'DG Bradman';
my_struct.batting_average = 99.94;
% Save struct to MATLAB file
save example_struct.mat my_struct
% Load struct from MATLAB file
load example_struct.mat
% View
my_struct
## my_struct =
##
## scalar structure containing the fields:
##
## rank = 1
## player = DG Bradman
## batting_average = 99.940
The ‘default’ method for importing CSVs - the csvread()
function - can only read numerical data. It puts this into a matrix:
csv = csvread('Input/example_csv.csv')
## csv =
##
## 0 0 0
## 1.0000 0 99.9400
## 2.0000 0 61.8700
## 3.0000 0 60.9700
## 4.0000 0 60.8300
## 5.0000 0 60.7300
To import both numbers and text (as a cell):
csv = fileread('Input/example_csv.csv');
csv = strsplit(csv, '\n');
for i = 1:length(csv)
csv_formatted(i, :) = strtrim(strsplit(csv{i}, ','));
endfor
printf('%5s %11s %s\n', csv_formatted'{:})
## rank player batting_average
## 1 DG Bradman 99.94
## 2 AC Voges 61.87
## 3 RG Pollock 60.97
## 4 GA Headley 60.83
## 5 H Sutcliffe 60.73
This works even if the CSV data is stored in text format, eg example_csv.txt
.
These can’t be imported in base Octave, but can be with the xlsread()
function from the io
package. Likewise, xlswrite()
can be used for exporting.
Note that files in the old Excel Binary File Format (.xls
) can’t be imported at all, and on macOS the xlsread()
and xlswrite()
functions don’t always work. Also note that there used to be functions odsread()
and odswrite()
but these have now been deprecated.
.xlsx
)pkg load io
% Import
[numarr, txtarr, rawarr, limits] = xlsread('Input/example_xlsx.xlsx');
% View
rawarr
% Export
xlswrite('Output/example_xlsx.xlsx', rawarr);
## rawarr =
## {
## [1,1] = rank
## [2,1] = 1
## [3,1] = 2
## [4,1] = 3
## [5,1] = 4
## [6,1] = 5
## [1,2] = player
## [2,2] = DG Bradman
## [3,2] = AC Voges
## [4,2] = RG Pollock
## [5,2] = GA Headley
## [6,2] = H Sutcliffe
## [1,3] = batting_average
## [2,3] = 99.940
## [3,3] = 61.870
## [4,3] = 60.970
## [5,3] = 60.830
## [6,3] = 60.730
## }
.ods
)pkg load io
% Import
[numarr, txtarr, rawarr, limits] = xlsread('Input/example_ods.ods');
% View
rawarr
% Export
xlswrite('Output/example_ods.ods', rawarr);
## rawarr =
## {
## [1,1] = rank
## [2,1] = 1
## [3,1] = 2
## [4,1] = 3
## [5,1] = 4
## [6,1] = 5
## [1,2] = player
## [2,2] = DG Bradman
## [3,2] = AC Voges
## [4,2] = RG Pollock
## [5,2] = GA Headley
## [6,2] = H Sutcliffe
## [1,3] = batting_average
## [2,3] = 99.940
## [3,3] = 61.870
## [4,3] = 60.970
## [5,3] = 60.830
## [6,3] = 60.730
## }
Configuration/initialisation files (.ini
) cannot be imported as such in Octave. There are three workarounds:
fileread()
INI files can be imported as blocks of text (single multi-line strings) using the fileread()
function. Given the following example_ini.ini
file:
First line
Second line
Third line
…we can import this as follows:
ini = fileread('example_ini.ini')
## ini = First line
## Second line
## Third line
When running a script, Octave searches for and runs any file named startup.m
in the working directory. Given startup.m
with the following content:
disp('This is the startup file')
…and script.m
in the same folder with the following:
disp('This is the script file')
…then running script.m
will produce the following:
This is the startup file
This is the script file
The argv()
function collects arguments passed to the script from the command line interface (CLI). Given a script example_script.m
with the following:
args = argv();
printf('args = %s\n', args{1});
…then running the following in the terminal:
$ octave example_script.m 'Hello, World!'
…will produce:
args = Hello, World!