⇦ Back

1 List Files

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.

1.1 Iterate Over the Files

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:

  • Use the numel() function to get this value - it returns the number of elements in a cell
  • Use a regular expression via the regexp() 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

1.2 Checking the Extension

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

2 Image Files

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.

  • Use fullfile() to create the full filepaths to the images
  • Use imread() to read the images into Octave
  • Multiple each of the pixel values by 0 to turn them black
  • Use imwrite() 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

3 Diary Files

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 recording
  • diary off will stop this recording
  • diary will toggle recording
  • diary {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

4 Text Files

4.1 Strings

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

4.2 Data Stored as Text Files

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')

5 MATLAB Files

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

6 Scalar Structures (Structs)

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

7 Comma-Separated Values (CSV Files)

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.

8 Other Spreadsheets

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.

8.1 Office Open XML (.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
## }

8.2 OpenDocument Spreadsheet (.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
## }

9 Initialisation Files

Configuration/initialisation files (.ini) cannot be imported as such in Octave. There are three workarounds:

9.1 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

9.2 Startup Files

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

9.3 Pass Command Line Arguments

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!

⇦ Back