Lua — преобразовать .txt список элементов в таблицу для последующего перебора

#lua

#lua

Вопрос:

У меня есть длинный системный список кодов (в text.txt файл), что я не могу понять, как преобразовать их все в подходящую структуру, которую я затем могу перебирать построчно.

 
Power
0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0ACD

Power$1
0000 006C 0022 0002 015B 00AD 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 05F7 015B 0057 0016 0E6C

Power$2
0000 0068 0000 0022 0169 00B4 0017 0044 0017 0044 0017 0017 0017 0017 0017 0017 0017 0044 0017 0017 0017 0044 0017 0017 0017 0017 0017 0044 0017 0044 0017 0044 0017 0017 0017 0044 0017 0017 0017 0044 0017 0017 0017 0017 0017 0044 0017 0044 0017 0017 0017 0017 0017 0044 0017 0017 0017 0044 0017 0044 0017 0017 0017 0017 0017 0044 0017 0044 0017 0017 0017 0636

Etc.
  

В идеале мне нужно добиться следующей последовательности.

  1. прочитайте / запишите имя команды (запишите его в журнал / другой текстовый файл),
  2. передайте соответствующий код (обновите журнал / txt, чтобы показать, что он был отправлен)
  3. подождите короткое время,
  4. перейдите к следующему в списке.

Комментарии:

1. Чтобы разделить ваш файл на строки: for line in io.lines"text.txt" do (do something with the current line) end

Ответ №1:

Вы можете решить это с помощью следующих функций:

io.lines('text.txt') : Возвращает функцию итератора, которая позволяет вам читать каждую строку файла.

io.open('log.txt', 'w'):write(content) : позволяет быстро выполнять запись в файл (состоящий из io.open которого возвращает вам дескриптор файла, и file:write ).

io.flush() : сбрасывает поток. Если поток сохранил какие-либо символы из write(), немедленно запишите их по назначению (сохраните файл).

string.find(pattern) : используя предоставленный шаблон, возвращает позицию найденных подстрок.

string.len() : возвращает длину строки, в примере я использовал ее, чтобы убедиться, что это не пустая строка.

table.concat(table, delimiter) : возвращает строку, содержащую все элементы таблицы, соединенные вместе, разделенные разделителем, указанным в качестве второго аргумента.

Если вам действительно нужно сделать паузу, используйте os.clock() which возвращает приблизительное количество в секундах процессорного времени, используемого программой.

Что-то подобное должно сработать для вас:

 local logFile = io.open('log.txt', 'w')
local logs = {} -- We will use this to log the messages to log.txt later 

local i = 1;for line in io.lines("text.txt") do
  -- %d represents digits, %A represents all non-letter characters this translates to: "if the line contains "$x" or only contains letters"
  if (line:find('$%d') or not line:find('%A')) and line:len() > 1 then
    logs[#logs  1] = 'Command: ' .. line
  elseif line:find('%d') then
    -- This will run if the sequence does not contain $x or only contains letters (such as Power$1 or Power)
    
    -- If you want to iterate through every single instruction, you can use %S  to separate by whitespaces
    local x = 1;for instruction in line:gmatch('%S ') do
      print('Instruction ' .. x .. ' at line ' .. i, instruction)
      x = x   1

      -- Wait 1 second (this allows you to read the current instruction but makes it slower)
      local pause = os.clock()
      repeat until os.clock() > pause   1
    end

    -- If you want to write it during the loop use logFile:write(content); logFile:flush(),
    -- otherwise append it to logs[#logs   1] and write it when the program is finished using table.concat()
    
    logs[#logs   1] = 'Sequence: ' .. line

    
  end; i = i   1 -- Raise the line number
end

-- Concatenate the information and save it to logs file

logFile:write(table.concat(logs, 'n'))
logFile:flush()
  

Это сгенерировало следующий вывод для log.txt:

 Command: Power
Sequence: 0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0ACD
Command: Power$1
Sequence: 0000 006C 0022 0002 015B 00AD 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 05F7 015B 0057 0016 0E6C
Command: Power$2
Sequence: 0000 0068 0000 0022 0169 00B4 0017 0044 0017 0044 0017 0017 0017 0017 0017 0017 0017 0044 0017 0017 0017 0044 0017 0017 0017 0017 0017 0044 0017 0044 0017 0044 0017 0017 0017 0044 0017 0017 0017 0044 0017 0017 0017 0017 0017 0044 0017 0044 0017 0017 0017 0017 0017 0044 0017 0017 0017 0044 0017 0044 0017 0017 0017 0017 0017 0044 0017 0044 0017 0017 0017 0636
  

И выводит на консоль следующее:

 Instruction 1 at line 3 0000
Instruction 2 at line 3 0070
Instruction 3 at line 3 0000
Instruction 4 at line 3 0032
Instruction 5 at line 3 0080
Instruction 6 at line 3 0040
Instruction 7 at line 3 0010
Instruction 8 at line 3 0010
Instruction 9 at line 3 0010
. . .
  

Комментарии:

1. Большое спасибо, к сожалению, вышеприведенное не совсем сработало. Распечатка дошла до строки 109, а затем началась снова, затем дошла до 96, а затем началась снова, а затем 102 и так далее, это просто продолжалось. И, поскольку казалось, что он постоянно перебирает файл — это в конечном итоге привело к сбою / перезагрузке Lua. Также каждая «последовательность» была записана несколько раз в файл журнала. под его ‘power ref. В текстовом файле есть 120 команд питания, если это поможет — есть ли способ просто выполнить итерацию / просмотр текста.1 один раз?

2. Я думаю, что строка / область, которая нуждается в исправлении, является локальной x = 1; для инструкции в строке:gmatch(‘% S ‘) do , я пробовал это с ($ x), а также только с первой частью x = 1

3. Извините, что не прояснил, команда, которую мне нужно отправить / протестировать, — это вся мощность строки = 0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 00100010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0010 0010 0030 0010 0030 0010 0030 0010 0ACD ) не каждый 4цифры

Ответ №2:

Большое спасибо за всю помощь, я использовал приведенный пример и адаптировал его к своим конкретным потребностям..

 local lfs = require "lfs"
local read_file_path = "/mnt/nas/vera/text1.txt" -- # path to your file here
local write_file_path = "/mnt/nas/vera/text2.txt" -- # path to your file here
local pattern1 = "^.*Power.*$" -- # your pattern to find
local pattern2 = "^.*0000.*$" -- # your pattern to find

local logFile = io.open(write_file_path, 'w')
local logs = {} -- We will use this to log the messages to log.txt later 

local i = 1;for line in io.lines(read_file_path) do
if (line:find(pattern1) or not line:find('%A')) and line:len() > 1 then
    local powerref = line
    logs[#logs  1] = 'Command: ' .. powerref
    elseif line:find(pattern2) then
      local ircode = line
      local x = 1 do
        print('Command ' .. x .. ' is "' .. ircode .. '" found on line ' .. i)
        x = x   1
      local pause = os.clock()
      repeat until os.clock() > pause   1
  end
         logs[#logs   1] = 'Sequence: ' .. line
  end; i = i   1 -- Raise the line number
end

logFile:write(table.concat(logs, 'n'))
logFile:flush()