处理 Lua 中的管道 IO

我搜索了很多资源,但无论如何都找不到答案。 我正在尝试执行以下操作:

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

我找不到任何关于在Lua中处理管道IO的资源,也无法弄清楚如何处理。 有没有一个好的、非hackish的方法来解决它? 最好是缓冲用于低内存使用,但如果这是唯一的替代方案,我将不得不一次读取整个文件。

如果必须将其写入临时文件然后加载到程序中,那将非常令人失望。

提前致谢。

点赞
用户90511
用户90511

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

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

缓冲由提供管道的操作系统负责。编写程序时不需要过多关注此问题。


编辑:显然,当您提到缓冲时,您是在考虑部分读取文件,而不是将整个文件加载到字符串中。io.read可以使用数字参数来从输入中读取一定数量的字节,如果无法读取任何字符,则返回nil

local size = 2^13      --好的缓冲区大小(8K)
while true do
  local block = io.read(size)
  if not block then break end
  io.write(block)
end
2015-03-16 22:34:10
用户3735873
用户3735873

另一个(更简单)的选择是 io.lines() 迭代器,但括号内没有文件名。例如:

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

UPDATE:要获取一定数量的字符,您可以在此基础上编写包装器。例如:

function io.chars(n,filename)
  n = n or 1                  -- 每次读取的默认字符数
  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
2015-03-17 19:47:46