Edit specific line in a file with lua - lua

I'm trying to edit a specific line in a file using lua.
For example, I have a file with 12 lines. I want to edit the 2nd line ONLY.
Line 1: Hello
Line 2: Hello again
The output file would be for example
Line 1: Hello
Line 2: Whatever
but without caring what's the content of the 2nd line. Just by the number of the line.

I figured it out after all. Here's the code:
function Initialize()
inputFile = 'PathToFile'
end
function Edit()
local file = io.open(inputFile, 'r')
local fileContent = {}
for line in file:lines() do
table.insert (fileContent, line)
end
io.close(file)
fileContent[3] = 'This line has been edited'
file = io.open(inputFile, 'w')
for index, value in ipairs(fileContent) do
file:write(value..'\n')
end
io.close(file)
end

Related

Read from one line with a specific content till another line with specific content in Lua. How?

In LUA, I would need to read a text file from a line with a specific content to another line with a specific content.
How can I do it please?
Here an example
a text file called: aaa.txt
...
...
...
[Main from here on]
line1
line2
line3
...
...
title=Till here
...
...
So I need to count the lines between and starting from the square brakets line [Main from here on] (it's titled so), till the last line called "title=Till here"
This solution is based on io.lines () iterator:
--[[
This function will return all lines from <file>
from <from> till <to> or end of file
both ends included.
--]]
local function readFromTo (file, from, to)
io.input (file) -- open file.
local started = false
local lines = {}
for line in io.lines () do
if not started and line == from then
started = true
end
if started then
lines [#lines + 1] = line
if line == to then
-- <to> found:
return lines
end
end
end
-- Only if <to> not found:
return lines
end
print (table.concat (readFromTo ('aaa.txt', '[Main from here on]', 'title=Till here'), '\n'))

how to fix: attempt to index global "f" (a nil value), LUA I/O text editing

As title says that error appears when executing the following code.
//open the file
local out = io.open('path', 'r')
//Fetch all lines and add them to a table
local lines = {}
for line in f:lines() do
table.insert(lines, line)
end
//close
out:close()
//insert line
table.insert(lines, 8, "test this bullshit\n")
//temporary file
local out = io.open('pathnew', 'w')
for _, line in ipairs(lines) do
out:write(line)
end
//close temporary
out:close()
//delete old file (from the first io.open)
os.remove('pathold')
//rename temporary file to the old one (from the first io.open)
os.rename('pathnew', 'pathold')
You are opening a file you call out but then try to read lines from a file you call f. f doesn’t exist.

Read specific line using lua

I want to read a specific line in lua. I have the following piece of code, but it's not working according to my needs, can anybody help?
#!/usr/bin/env lua
local contents = ""
local file = io.open("IMEI.msg", "r" )
if (file) then
-- read all contents of file into a string
contents = file:read()
file:close()
print(contents)
specific = textutils.unserialize(contents)
print(specific[2])
else
print("file not found")
end
If you just need to read one line, creating a table of all lines is unnecessary. This function returns the line without creating a table:
function get_line(filename, line_number)
local i = 0
for line in io.lines(filename) do
i = i + 1
if i == line_number then
return line
end
end
return nil -- line not found
end
You can use io.lines for this. io.lines returns an iterator over the lines in the file. If you want to access a specific line, you will first have to load all the lines into a table.
Here's a function that pulls the lines of a file into a table and returns it:
function get_lines(filename)
local lines = {}
-- io.lines returns an iterator, so we need to manually unpack it into an array
for line in io.lines(filename) do
lines[#lines+1] = line
end
return lines
end
You can index into the returned table to get the specified line.

reading special lines in lua

I am searching for the easiest way to read a string which is located in a file with a variable number of lines behind:
UserName=herecomesthestring
I thought about hardcoding a the linenumber, but this won't work, because in this file, the UserName can be more then once and the line numbers aren't the same (from user to user they may change).
Read the file line-by-line
Match the line and extract the username
Put it in a list
function getusers(file)
local list, close = {}
if type(file) == "string" then
file, close = io.open(file, "r"), true
end
for line in file:lines() do
local user, value = line:match "^([^=]+)=([^\n]*)$"
if user then -- Dropping mal-formed lines
table.insert(list, user)
list[user] = value -- Might be of interest too, so saving it
end
end
if close then
file:close()
end
return list
end
Call with either a file or a filename.
I edited the function above a bit, now it works more or less, just need to edit the RegEx.
function getusers(file)
local list, close = {}
local user, value = string.match(file,"(UserName=)(.*)")
print(value)
f:close()
end

Save a textarea into a file using lua

i have a webserver (uhttpd) that uses CGI with LUA.
I made a form with a textarea.
What i need is saving the content of the textarea on a file located in /etc/list.txt
I think that the LUA script have to read the POST variables, and then save them into a local file /etc/list.txt.
I already have the script for reading the file:
function file_exists(file)
local f = io.open(file, "rb")
if f then f:close() end
return f ~= nil
end
function lines_from(file)
if not file_exists(file) then return {} end
lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end
return lines
end
local file = '/etc/list.txt'
local lines = lines_from(file)
print ('<textarea name="mensaje" cols="40" rows="40">')
for k,v in pairs(lines) do
print(v)
end
print ("</textarea>")
This script shows me the content of file.txt onto the textarea.
Now i need a button "Save" that POST the textarea again into the file.
Thank you for your help and have a good day.
Small critique: lines_from files is overwriting a global variable lines every time it is called. That should be made local. Also opening and closing the file to see if it exists before reading it is wasteful. That operation can be folded into lines_from:
function lines_from(filename)
local lines = {}
local file = io.open(filename)
if file then
for line in file:lines(file) do
lines[#lines + 1] = line
end
file:close();
end
return lines
end
In your case there's no reason to even read the text as lines. Just read all the file's text:
function text_from(filename)
local text = ''
local file = io.open(filename)
if file then
text = file:read('*a')
file:close();
end
return text
end
local file = 'test.lua'
local text = text_from(file)
print ('<textarea name="mensaje" cols="40" rows="40">')
print(text)
print ("</textarea>")
To write the text back to the file, just reverse the procedure, opening the file in "w+" mode (replace existing data):
function save_text_to(filename, text)
local file = io.open(filename, 'w+')
if file then
text = file:write(text);
file:close();
end
end
save_text_to('foo', text)

Resources