-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimplecsv.lua
More file actions
executable file
·131 lines (102 loc) · 3.49 KB
/
simplecsv.lua
File metadata and controls
executable file
·131 lines (102 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
--[[
-------------------------------
Save this file as simplecsv.lua
-------------------------------
Example use: Suppose file csv1.txt is:
1.23,70,hello
there,9.81,102
x,y,,z
8,1.243,test
Then the following
-------------------------------------
local csvfile = require "simplecsv"
local m = csvfile.read('./csv1.txt') -- read file csv1.txt to matrix m
print(m[2][3]) -- display element in row 2 column 3 (102)
m[1][3] = 'changed' -- change element in row 1 column 3
m[2][3] = 123.45 -- change element in row 2 column 3
csvfile.write('./csv2.txt', m) -- write matrix to file csv2.txt
-------------------------------------
will produce file csv2.txt with the contents:
1.23,70,changed
there,9.81,123.45
x,y,,z
8,1.243,test
the read method takes 4 parameters:
path: the path of the CSV file to read - mandatory
sep: the separator character of the fields. Optionsl, defaults to ','
tonum: whether to convert fields to numbers if possible. Optional. Defaults to true
null: what value should null fields get. Optional. defaults to ''
]]
module(..., package.seeall)
---------------------------------------------------------------------
function string:split(sSeparator, nMax, bRegexp)
if sSeparator == '' then
sSeparator = ','
end
if nMax and nMax < 1 then
nMax = nil
end
local aRecord = {}
if self:len() > 0 then
local bPlain = not bRegexp
nMax = nMax or -1
local nField, nStart = 1, 1
local nFirst,nLast = self:find(sSeparator, nStart, bPlain)
while nFirst and nMax ~= 0 do
aRecord[nField] = self:sub(nStart, nFirst-1)
nField = nField+1
nStart = nLast+1
nFirst,nLast = self:find(sSeparator, nStart, bPlain)
nMax = nMax-1
end
aRecord[nField] = self:sub(nStart)
end
return aRecord
end
---------------------------------------------------------------------
function read(path, sep, tonum, null)
tonum = tonum or true
sep = sep or ','
null = null or ''
local csvFile = {}
local file = assert(io.open(path, "r"))
for line in file:lines() do
fields = line:split(sep)
if tonum then -- convert numeric fields to numbers
for i=1,#fields do
local field = fields[i]
if field == '' then
field = null
end
fields[i] = tonumber(field) or field
end
end
table.insert(csvFile, fields)
end
file:close()
local num_rows = #csvFile -- Output: Number of rows:
local num_cols = #csvFile[1] -- Output: Number of columns:
print("num_rows = "..num_rows .. " num_cols = " ..num_cols)
for i_ind = 2, num_rows do
for j_ind = 1, num_cols do
if (type(csvFile[i_ind][j_ind]) == nil or type(csvFile[i_ind][j_ind]) ~= "number") then
print ("Invalid Input parametrs (ERROR) value[" .. i_ind-1 .."][".. j_ind .."] = " .. type(csvFile[i_ind][j_ind])); exit();
end
end
end
return csvFile,num_rows,num_cols
end
---------------------------------------------------------------------
function write(path, data, sep)
sep = sep or ','
local file = assert(io.open(path, "w"))
for i=1,#data do
for j=1,#data[i] do
if j>1 then file:write(sep) end
file:write(data[i][j])
end
file:write('\n')
end
file:close()
end
---------------------------------------------------------------------