在 Lua 中处理管道 io

Handling piped io in Lua

我为此搜索了很多,但找不到答案。我正在尝试执行以下操作:

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

我在 Lua 中没有找到关于处理管道 io 的单一资源,也不知道如何去做。有没有一种好方法,非骇人听闻的方法来解决它?最好缓冲以降低内存使用量,但如果那是唯一的选择,我会接受一次读取整个文件。

要是写成一个临时文件,然后加载到程序中,那真是令人失望。

提前致谢。

标准库有一个 io.stdin 和一个 io.stdout,您可以将它们用于输入和输出而无需求助于临时文件。您还可以使用 io.read 代替 someFile:read,默认情况下它将从标准输入读取。

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

另一个(更简单的)替代方法是 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