I'm using this script https://github.com/mpv-player/mpv/blob/master/TOOLS/lua/autoload.lua
Sometimes when open such file, I want to loop current file. Normally for that I use:
#L cycle-values loop-file "inf" "no" # toggle infinite looping
but this doesn't work in this situation.
This might work.
L cycle-values loop "inf" "no"
Related
I am learning the Lua IO library. I'm having trouble with io.write(). In Programming Design in Lua, there is a piece of code that iterates through the file line by line and precedes each line with a serial number.
This is the file I`m working on:
test file: "iotest.txt"
This is my code
io.input("iotest.txt")
-- io.output("iotest.txt")
local count = 0
for line in io.lines() do
count=count+1
io.write(string.format("%6d ",count), line, "\n")
end
This is the result of the terminal display, but this result cannot be written to the file, whether I add IO. Output (" iotest.txt ") or not.
the results in terminal
This is the result of file, we can see there is no change
The result after code running
Just add io.flush() after your write operations to save the data to the file.
io.input("iotest.txt")
io.output("iotestout.txt")
local count = 0
for line in io.lines() do
count=count+1
io.write(string.format("%6d ",count), line, "\n")
end
io.flush()
io.close()
Refer to Lua 5.4 Reference Manual : 6.8 - Input and Output Facilities
io.flush() will save any written data to the output file which you set with io.output
See koyaanisqatsi's answer for the optional use of file handles. This becomes especially useful if you're working on multiple files at a time and gives you more control on how to interact with the file.
That said you should also have different files for input and output. You'll agree that it doesn't make sense to read and write from and to the same file alternatingly.
For writing to a file you need a file handle.
This handle comes from: io.open()
See: https://www.lua.org/manual/5.4/manual.html#6.8
A file handle has methods that acts on self.
Thats the function after the : at file handle.
So io.write() puts out on stdout and file:write() in a file.
Example function that can dump a defined function to a file...
fdump=function(func,path)
assert(type(func)=="function")
assert(type(path)=="string")
-- Get the file handle (file)
local file,err = io.open(path, "wb")
assert(file, err)
local chunk = string.dump(func,true)
file:write(chunk)
file:flush()
file:close()
return 'DONE'
end
Here are the methods, taken from io.stdin
close = function: 0x566032b0
seek = function: 0x566045f0
flush = function: 0x56603d10
setvbuf = function: 0x56604240
write = function: 0x56603e70
lines = function: 0x566040c0
read = function: 0x56603c90
This makes it able to use it directly like...
( Lua console: lua -i )
> do io.stdout:write('Input: ') local result=io.stdin:read() return result end
Input: d
d
You are trying to open the same file for reading and writing at the same time. You cannot do that.
There are two possible solutions:
Read from file X, iterate through it and write the result to another file Y.
Read the complete file X into memory, close file X, then delete file X, open the same filename for writing and write to it while iterating through the original file (in memory).
Otherwise, your approach is correct although file operations in Lua are more often done using io.open() and file handles instead of io.write() and io.read().
My script uses lfs to read files in a directory.
It then stores the value in a variable called file.
The problem is the value is actually a list.
Here is a sample value.
.
..
a.txt
b.txt
c.txt
d.txt
I can print this variable as is, but I need to integrate this variable inside a dialog box.
When I integrate this variable inside a dialog box, it prints each line in a new dialog.
Here is my code:
require 'lfs'
function main()
for file in lfs.dir[[C:\Users\QXJtaW5pdXM\Desktop\Test\test_3.4.5.6]] do
print(file)
--This works perfectly fine.
Dialog("Title", "Files:\n" .. file)
--This prints each line in a new dialog box.
end
end
return main
I need to print all the files in one dialog box.
If at all possible, I'd love to avoid printing . & ..
As a picture reference, here is what I get:
https://imgur.com/tmfQlan
Here is what I need:
https://imgur.com/mxYBO9t
Could someone please point me in the right direction?
Thank you very very very much!
Your loop's body is executed once for every file so what do you expect if you create a dialog inside the loop? Create it outside after you've created a list of files.
require 'lfs'
function main()
local files = ""
for file in lfs.dir[[C:\Users\QXJtaW5pdXM\Desktop\Test\test_3.4.5.6]] do
files = files .. file .. "\n"
end
Dialog("Title", "Files:\n" .. files)
end
Maybe there is also another function that gives you a list of file names right away.
I had to use table.insert in a for loop to add values inside a table file_list.
Then use table.remove to remove the first two inputs . & ..
In the end, the code would look something like this:
require 'lfs'
file_list = {}
function main()
for grab_files in lfs.dir[[C:\Users\QXJtaW5pdXM\Desktop\Test\test_3.4.5.6]] do
table.insert(file_list, grab_files)
-- table.insert will assign each input of grab_files into each reference of file_list table
end
table.remove(file_list,1)
-- This removes the '.'
table.remove(file_list,1)
-- This removes the '..'
file_names = table.concat(file_list, "\n")
Dialog("Title", "Files:\n" .. file_names)
end
return main
I am using a luvit Lua environment to run my lua code through my control panel. I am looking to write to a .txt file, but with the simple code that i am running, its not working.
The reason I wish to write to a .txt file is to log notices from my Discord Bot I am working on in the Discordia library.
I have a folder called MezzaBOT. In this file i have a write.lua file and also a log.txt file. I have this simple code in my write.lua file:
io.output('log.txt')
io.write('hello\n')
io.close()
I then run in my command promt with Luvit environment:
>luvit Desktop\mezzabot\write.lua
I don't get any errors but the log.txt file continues to stay empty. Am I missing a line in my code, or do i need to access log.txt differently?
edit: my new code is the following
file = io.open('log.txt')
file:write('hello', '\n')
file:close()
and it is not making a new line for each time with \n
edit B:
Ok, i found my problem, its creating a log.txt in my C:\Users\PC.
One other problem is when writing, its not making a new line with the \n. Can someone please help me?
Lua, by default, opens files in read mode. You need to explicitly open a file in write mode if you want to write to it (see manual)
file = io.open('log.txt', 'w')
file:write('hello', '\n')
file:close()
Should work :)
For example, I have arbitrary lines in this format:
directory C:\Program Files\abc\def\
or something like.
log-enabled On
I want to be able to extract the "C:\Program Files\ab\def\" part out of that first line. Likewise, I want to extract the "On" out in the second line. The spaces between the variable and its value are arbitrary. I will know the name of the variable, but I need extract the value based on that.
So basically, I want to remove the first word and a number of arbitrary spaces that follow the first word, and return what remains until the end of the line.
Assuming that, by "word" you mean "a string of characters without spaces", you can do this:
for line in ioFile:lines() do
local variable, value = line:match("(%S+)%s+(.+)")
... --Do stuff with variable and value
end
One alternative with string.match was shown by Nicol Bolas, here is another alternative:
function splitOnFirstSpace(input)
local space = input:find(' ') or (#input + 1)
return input:sub(1, space-1), input:sub(space+1)
end
Usage:
local command, param = splitOnFirstSpace(line)
If no argument is given (splitOnFirstSpace('no-param-here')), then param is the empty string.
I do not believe Lua is packaged with a split() function like Ruby or Perl.
I found that this guy built a lua version of Perl's split function:
http://lua-users.org/lists/lua-l/2011-02/msg01145.html
If you can guarantee that the argument will only have 1 word before it, with that word not containing any spaces, you can read in that line, run the split function on it, and use the return array's 1 index value as what you want.
You could error check that too and make sure you get a 'C:\' within your expected directory, or check to make sure the string is == to 'On' or 'Off'. Because of using the hardcoded index value I really advocate you error check your expected value. Nothing is worse than having an assumed value be wrong.
If an error is detected make sure to log or print it to the screen so you know about it.
This could catch bugs where maybe the string that was input is improper.
Some simple code that models what I suggest you do:
line = "directory C:\Program Files\abc\def/";
contents = line.split(" "); --Split using a space
directory = contents[2]; --Here is your directory
if(errorCheckDir(directory))
--Use directory
end
EDIT:
In response to comments below Lua indeed begins indexing at 1, not 0.
Also, in the case that the directory contains spaces (which is probable) instead of simply using contents[2], I would loop through all of contents except index 1, and piece back together the directory making sure to add the required space between each index that you attach.
So in the case above, contents[2] and contents[3] would have to be stitched back together with a space in between to recover the proper directory.
directory = contents[2].." "..contents[3]
This can be easily automated using a function which has a loop in it and returns back the proper directory:
function recoverDir(contents)
directory = "";
--Recover the directory
for i=2, table.getn(contents) do
directory = directory..contents[i].." ";
end
--strip extra space on the end
dirEnd = string.len(directory);
directory = string.sub(directory,1,dirEnd-1);
return directory; --proper directory
end
I am opening a CSV file for writing with the following code, as indicated in CSV documentation here (http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html):
CSV.open( csv_file_out, 'wb' ) { |csv_line_out|
#stuff happens here
}
the block does not execute, i.e. after the CSV.open command debugger goes directly to the end of block.
thinking "just in case", I try the same with IO modes w+b wt w+t ab a+b. I also tried creating the file before the in case there was a problem with opening it. nothing changes.
when I stop the debugger at the CSV.open line, I am able to execute a block manually and create a csv file myself. I can also create the file frmo the exact same command from console. But it won't work when executed in the server.
Any ideas on what's going on are very welcome. Thanks in advance!
You don't need the {} brackets before your |csv_line_out|
Your trying to iterate sth. (the files content) that does not exist so its logical that it ends imediatly! Try it this way:
CSV.open(csv_file_out, "wb") do |csv|
csv << [column1, column2,...]
end