Тема: AHK: Поиск последней строки в .txt
Здравствуйте форумчане.
Появился у меня такой вопрос: Как отобразить в msgbox последнею строку текстового документа? Т.е то, что в ней написано.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Здравствуйте форумчане.
Появился у меня такой вопрос: Как отобразить в msgbox последнею строку текстового документа? Т.е то, что в ней написано.
Смотрите в справке второй пример к команде Loop (чтение файла).
ypppu А можно ли сделать чтение 2-й строки с конца например?
Используйте библиотеку TF для этой цели.
svoboden
Брал с ahkWiki, тоже работает.
Loop, read, trap.txt
last_line := A_LoopReadLine
MsgBox, %last_line%
Без этой библиотеки значит никак?
MsgBox % Func(A_ScriptFullPath, 2)
Func(FilePath, Line) {
FileRead, Text, *t %FilePath%
RegExReplace(Text, "m`a)$", "", Row)
FileReadLine, LineText, %FilePath%, % Row - Line + 1
Return LineText
}
MirchikAhtung, можно, конечно, складывать переменные:
LastLine := A_LoopReadLine
Line := LastLine
Но я бы так не делал.
Используйте библиотеку TF для этой цели.
Я бы не использовал эту библиотеку, недоделанная она:
#Include tf.ahk
TestFile=1`r2`r3
FileDelete, TestFile.txt
FileAppend, %TestFile%, TestFile.txt
F=TestFile.txt
MsgBox % TF_ReadLines("TestFile.txt",3)
Лучше наверное так, не надо 2 раза открывать файл, легко переделать на простой текст, можно указать строку сначала.
MsgBox % NeedLine(A_ScriptFullPath, -1)
NeedLine(FilePath, Line) {
FileRead, Text, %FilePath%
Text := StrReplace(StrReplace(Text, "`r`n", "`n"), "`r", "`n") "`n"
s := InStr(Text, "`n", 0, (Line > 0), Abs(Line - 1)) + 1
Return SubStr(Text, s, InStr(Text, "`n", 0, (Line > 0), Abs(Line)) - s)
}
И добавить если указанная строка больше кол-ва строк в тексте, то при запросе назад показать первую строку, при запросе вперед показать последнюю строку.
MsgBox % NeedLine("first row`r`nsecond row`r`nlast row", 4)
MsgBox % NeedLine("first row`r`nsecond row`r`nlast row", -4)
NeedLine(Text, Line) {
Text := StrReplace(StrReplace(Text, "`r`n", "`n"), "`r", "`n") "`n"
StrReplace(Text, "`n", "", Count)
Abs(Line) > Count && (Line := (Line > 0) ? Count : 1)
s := InStr(Text, "`n", 0, (Line > 0), Abs(Line - 1)) + 1
Return SubStr(Text, s, InStr(Text, "`n", 0, (Line > 0), Abs(Line)) - s)
}
Или так:
filePath := "D:\Downloads\test.txt"
MsgBox, % FileReadLineFromEnd(filePath, 2)
FileReadLineFromEnd(filePath, nLineFromEnd) {
FileRead, text, % filePath
arr := StrSplit(text, "`n", "`r")
Return arr[ObjMaxIndex(arr) - nLineFromEnd + 1]
}
teadrinker, так не получается:
TestFile=1`r2`r3
FileDelete, TestFile.txt
FileAppend, %TestFile%, TestFile.txt
MsgBox, % FileReadLineFromEnd("TestFile.txt", 2)
FileReadLineFromEnd(filePath, nLineFromEnd) {
FileRead, text, % filePath
arr := StrSplit(text, "`n", "`r")
Return arr[ObjMaxIndex(arr) - nLineFromEnd + 1]
}
Я с такими файлами не сталкивался.
И добавить если указанная строка больше кол-ва строк в тексте, то при запросе назад показать первую строку, при запросе вперед показать последнюю строку.
Но ведь это не отвечает запросу.
Я просто добавил чтобы было понятно как определять если запрос превышает кол-во строк.
Или так:
Я тоже сразу подумал про StrSplit, но загонять в массив например 5000 строк ради вывода одной, кажется избыточным.
Наверняка ТС читает какой нибудь лог, и он со временем разрастается. Когда речь про какие нибудь последние строки в файле, это похоже на поиск новой инфо в логе, тогда проще так.
serzh82saratov А эту функцию можно засунуть под
var := % NeedLine(A_ScriptFullPath, -1)
; например??
Не понял.
serzh82saratov Функция считывает с конца файла 2 строки, в которых указаны 2-е координат.
.
varX := % NeedLine(A_ScriptFullPath, 4)
и
varY := % NeedLine(A_ScriptFullPath, 6)
Координаты кнопке устанавливаем как
Gui, Add, Button, x%varX%y%varY%, Button
Но так - не выходит.
Так зачем так читать, если есть IniRead. И почему A_ScriptFullPath, если тогда в самом скрипте они могут быть прописаны как переменные.
Как же сильно я промахнулся с предположением про лог файл.)
Если пробел поставить, то должно работать.
x%varX%y%varY%
varX := NeedLine(A_ScriptFullPath, -4)
varY := NeedLine(A_ScriptFullPath, -6)
MsgBox % varX "`n" varY
Gui, Add, Button, x%varX% y%varY%, Button
NeedLine(FilePath, Line) {
FileRead, Text, %FilePath%
Text := StrReplace(StrReplace(Text, "`r`n", "`n"), "`r", "`n") "`n"
s := InStr(Text, "`n", 0, (Line > 0), Abs(Line - 1)) + 1
Return SubStr(Text, s, InStr(Text, "`n", 0, (Line > 0), Abs(Line)) - s)
}
OFF: Если файл очень большой, и нужно прочитать определённую строчку с конца, то наиболее экономичным способом будет что-то вроде этого:
FileReadLineFromEnd(filePath, nLineFromEnd) {
oFile := FileOpen(filePath, "r")
oFile.Pos := oFile.Length
(!(enc := oFile.Encoding) && enc := "cp0")
charLen := enc = "UTF-16" ? 2 : 1
i := 0
Loop {
oFile.Pos -= charLen, prevPos := oFile.Pos
if (oFile.Pos < 0 && notFound := true)
break
char := oFile[ "Read" . (enc = "UTF-16" ? "UShort" : "UChar") ]()
if (char = 10 || char = 13) {
if ( prevChar = (char = 10 ? 13 : 10) )
prevChar := ""
else
i++, prevChar := char
}
if (i = nLineFromEnd)
break
oFile.Pos := prevPos
}
( !notFound && str := oFile.ReadLine() ), oFile.Close()
Return RTrim(str, "`r`n")
}
OFF:
OFF: Если файл очень большой, и нужно прочитать определённую строчку с конца, то наиболее экономичным способом будет что-то вроде этого:
А не хотите OLE DB опробовать, как здесь: VBScript: работа с большими текстовыми файлами? AHK ж уже давно научился в Automation. Конечно, файлы должны быть реально большими, бо с нынешними гигабайтами оперативной памяти и ReadAll не слишком медленно будет.
alexii, спасибо, гляну.
serzh82saratov Маленькое продолжение темы.
varX := NeedLine(A_ScriptFullPath, -4)
varY := NeedLine(A_ScriptFullPath, -6)
Gui, Show, x%varX% y%varY%
NeedLine(FilePath, Line) {
FileRead, Text, usa.txt
Text := StrReplace(StrReplace(Text, "`r`n", "`n"), "`r", "`n") "`n"
s := InStr(Text, "`n", 0, (Line > 0), Abs(Line - 1)) + 1
Return SubStr(Text, s, InStr(Text, "`n", 0, (Line > 0), Abs(Line)) - s)
}
Такое вообще возможно сделать, чтобы функция NeedLine читала текст не с текстового документа, а с Gui, и Text, в котором и присутствуют строки (которые будут читаться функцией) будет выводиться как координаты в Gui, Show.
p.s Старался как можно внятней изложить мою мысль.
Можно, но такой ерундой никто не будет заниматся.
Вы хотите простое сделать сложным. Лучше поясните что имеется, и что нужно в итоге.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться