2015-03-16 3 views
1

Я много искал для этого, но не могу найти ответы нигде. Я пытаюсь сделать что-то вроде следующего:Обращение с трубопроводом io в Lua

cat somefile.txt | grep somepattern | ./script.lua

Я не нашел ни одного ресурса на обработку водопроводной ИО в Lua, и не могу понять, как это сделать. Есть ли хороший способ, не хакерский способ справиться с этим? Предпочтительно буферизуется для более низкого использования памяти, но я соглашусь на чтение всего файла сразу, если это единственная альтернатива.

Было бы очень неутешительно записывать его во временный файл, а затем загружать его в программу.

Заранее спасибо.

ответ

3

Стандартная лиратура имеет io.stdin и io.stdout, которые вы можете использовать для ввода и вывода без хавива для обращения к временным файлам. Вы также можете использовать io.read isntead someFile:read, и по умолчанию он будет считываться из stdin.

http://www.lua.org/pil/21.1.html

Буферные несет ответственность операционной системы, которая предоставляет трубу. Вам не нужно слишком беспокоиться об этом при написании своих программ.


редактировать: Очевидно, когда вы упомянули буферизацию вы думали о чтении части файла, в отличии от загрузки всего файла в строку. io.read может принимать числовой параметр для чтения до определенного количества байтов от ввода, возвращая nil, если символы не могут быть прочитаны.

local size = 2^13  -- good buffer size (8K) 
while true do 
    local block = io.read(size) 
    if not block then break end 
    io.write(block) 
end 
+1

Этот последний фрагмент страницы - это то, что улажено для меня, было бы здорово, если бы вы включили этот пример в свой ответ. Это именно то, что я имел в виду под буферизацией. Это эквивалентно чтению n байтов из stdin в массив, вместо того, чтобы вытащить весь файл сразу в память в C. Спасибо. –

1

Другой (проще) альтернативой является io.lines() итератора, но без имени файла внутри скобок. Пример:

for line in io.lines() do 
    print(line) 
end 

ОБНОВЛЕНИЕ: Чтобы получить несколько символов, вы можете написать обертку вокруг этого. Пример:

function io.chars(n,filename) 
    n = n or 1     --default number of characters to read at a time 
    local chars = '' 
    local wrap, yield = coroutine.wrap, coroutine.yield 
    return wrap(function() 
       for line in io.lines(filename) do 
        line = chars .. line .. '\n' 
        while #line >= n do 
        yield(line:sub(1,n)) 
        line = line:sub(n+1) 
        end 
        chars = line 
       end 
       if chars ~= '' then yield(chars) end 
       end) 
end 

for text in io.chars(30) do 
    io.write(text) 
end 
+0

Напоминает мне о Python, спасибо за подсказку! Есть ли способ для этого вместо чтения строки, читая символы 'n'? –

Смежные вопросы