lua 怎么读取txt文件最后一行内容?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua 怎么读取txt文件最后一行内容?相关的知识,希望对你有一定的参考价值。

让io.lines走到最后然后再读取可以么?或者怎么用find方法找出符合条件的最后一个字符串后面的内容?就是怎么找到正则表达式最后一个匹配到的结果?

【1】最简单的 就是不考虑文本大小,一次性读入,然后正则匹配

local text = [[
lua 怎么读取txt文件最后一行内容?

1 让io.lines走到最后然后再读取可以么?
2 或者怎么用find方法找出符合条件的最后一个字符串后面的内容?
3 就是怎么找到正则表达式最后一个匹配到的结果?

]]


local path = [[d:\\1.txt]]

--[==[
assert(not io.open(path, "r"), "Temp file already exists !")

-- 写测试文件
local file = io.open(path, "w+")
file:write(text)
file:close()
--]==]


local file = io.open(path, "r+");
local text = file:read("*all");
local regex = "([^\\n]+)$"       -- 匹配最后一行,最后一行为空行,则找不到
local regex = "([^\\n]+)[\\n]*$"  -- 匹配最后一行有效文本 $表示匹配字符串结尾位置
for line in string.gmatch(text, "([^\\n]+)[\\n]*$") do
    print(line)
end
file:close();


【2】如果文件超大,内存不够一次性读入文件,效率低点可以 按行遍历,找到行,在检查条件等等

考虑效率 应该 利用文件指针,先计算文件大小,然后分析出 读入文件块的大小,比如说 按8K读入,然后从文件尾向前推8K,一次性读入该字块,然后搜索换行符,如果找不到 继续递推读入直到找到换行,如果有换行,就转换成第一步 正则匹配


【附录】 

-- 文件指针 操作
local cur_pos = file:seek()
file:seek("end")
file:seek("set", pos)

-- 由于单行读取遍历 
local file = io.open(path, "r+");
for line in file:lines() do
    last_line = line
end

参考技术A #!/usr/bin/lua

if arg[1] == "-n" then
    tail_lines = arg[2]
    filepath = arg[3]
else
    tail_lines = 10
    filepath = arg[1]
end

-- 一次读取512字节数据
read_byte_once = 512
offset = 0
fp = io.open(filepath,"r")
if fp == nil then
    print("open file "..filepath.." failed.")
    os.exit(0)
end
line_num = 0
while true do
    -- 每次偏移read_byte_once字节
    offset = offset - read_byte_once
    -- 以文件尾为基准偏移offset
    if fp:seek("end",offset) == nil then
        -- 偏移超出文件头后将出错,这时如果是第一次读取的话,直接将文件指针偏移到头部,否则跳出循环输出所有内容
        if offset + read_byte_once == 0 then
            fp:seek("set")
        else
            break
        end
    end
    data = fp:read(read_byte_once)
    -- 倒转数据,方便使用find方法来从尾读取换行符
    data = data:reverse()
    index = 1
    while true do
        -- 查找换行符
        start = data:find("\\n",index, true)
        if start == nil then
            break
        end
        -- 找到换行符累加
        line_num = line_num + 1
        -- 找到足够换行符
        if tail_lines + 1 == line_num then
            -- 偏移文件符指针到第line_num个换行符处
            fp:seek("end",offset+read_byte_once-start+1)
            io.write(fp:read("*all"))
            fp:close()
            os.exit(0)
        end
        index = start + 1
    end
end

-- 找不到足够的行,就输出全部
fp:seek("set")
io.write(fp:read("*all"))
fp:close()

用法:

./tail.lua centos.log

./tail.lua -n 20 centos.log

参考:https://www.centos.bz/2017/04/read-the-last-n-lines-with-lua-tail/

21 读取文件最后一行

1,当读取的文件不大时

#coding:utf-8
‘‘‘
fname为所读xx.txt文件
输出为:文件第一行和最后一行
‘‘‘

fname = test.txt
with open(fname, r) as f:  #打开文件
    lines = f.readlines() #读取所有行
    first_line = lines[0] #取第一行
    last_line = lines[-1] #取最后一行
    print(文件%s第一行为: % first_line)
    print(文件%s最后一行为:% last_line)

2,当文件比较大时,readlines()会一次性读取全部数据到内存,会浪费内存资源。

#coding:utf-8
‘‘‘
f_name为所读xx.txt文件
输出为:文件最后一行
‘‘‘

fname = test.txt
with open(fname, r) as f:  #打开文件
    first_line = f.readline()  #读第一行
    off = -50      #设置偏移量
    while True:
        f.seek(off, 2) #seek(off, 2)表示文件指针:从文件末尾(2)开始向前50个字符(-50)
        lines = f.readlines() #读取文件指针范围内所有行
        if len(lines)>=2: #判断是否最后至少有两行,这样保证了最后一行是完整的
            last_line = lines[-1] #取最后一行
            break
        #如果off为50时得到的readlines只有一行内容,那么不能保证最后一行是完整的
        #所以off翻倍重新运行,直到readlines不止一行
        off *= 2
    print(‘文件%s第一行为:‘ % first_line)
    print(‘文件%s最后一行为:‘% last_line)

 

以上是关于lua 怎么读取txt文件最后一行内容?的主要内容,如果未能解决你的问题,请参考以下文章

lua文本读取账号密码分割登录

c#中怎么读取txt文件的最后几行

C++怎么在txt文件读取中一行一行的读内容

python读取txt文件最后一行(文件大+文件小)

python文件读取到最后一行后怎么返回第一行

java I/O 读取一个txt文件中每一个空行之后的第一行,怎么办?