Что нового

Как удалить последнюю строку текстового файла?

akoulev

Новичок
Сообщения
169
Репутация
2
Версия AutoIt:
3.3.0.0
Описание:
Как удалить последнюю строку текстового файла?
Циклом считаю количество строк; в ini-файле беспроблемно убрал бы строку, но файл-то не ini-шный, а вовсе txt-шный.
Примечания:
Вот такая строка меня бы устроила целиком и полностью:
$linia=FileDeleteLine($file, $nmer);
вся беда в том, что в AutoIt-е НЕТ такой функции: FileDeleteLine !!!!

Если можно, кусочек кода приветствуется! ;)
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
смотри справку по UDF. тема _FileWriteToLine
можно перезаписывать любую строку
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
А такая устроит ?
#Include <File.au3>
_FileWriteToLine ( $file, _FileCountLines($file), '', 1)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
А при чём тут стол заказов?! Переношу...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
akoulev [?]
в AutoIt-е НЕТ такой функции: FileDeleteLine !!!!
Её можно сделать:

Код:
_FileDeleteLine("File.txt", 3)

Func _FileDeleteLine($sFile, $iLine)
	$hFile = FileOpen($sFile, 0)
	If $hFile = -1 Then Return SetError(1, 0, 0)
	
	$sFileContent = ""
	$aFileContent = StringSplit(StringStripCR(FileRead($hFile)), @LF)
	
	FileClose($hFile)
	
	For $i = 1 To $aFileContent[0]
		If $i <> $iLine Then $sFileContent &= $aFileContent[$i] & @CRLF
	Next
	
	$hFile = FileOpen($sFile, 2)
	If $hFile = -1 Then Return SetError(2, 0, 0)
	
	FileWrite($hFile, StringTrimRight($sFileContent, 2))
	Return FileClose($hFile)
EndFunc
 
Сообщения
28
Репутация
-3
второйц вариант кода- оч большой по сравнению с первым,его навернон заминусуют.

Новичку, открывшему тему - Автоиту параллельно (||) что ты пишеш INI-данные не в фаил с расширением INI. пиши хоть в EXE или BIN , все арвно автоит при чтении открывает фаил кака RAW, то есть как будто блокнотом (назовем это так). так что проьлема удаления строки навернон для тебясама отпала. вот
Плюсуйте :-[
 
Автор
A

akoulev

Новичок
Сообщения
169
Репутация
2
Core2Duo сказал(а):
второй вариант кода - очень большой, по сравнению с первым; его, наверное, заминусуют.
За что тут минусовать? 8-O Я только плюсую - как минимум, за проявленное внимание к моей проблеме.
Core2Duo сказал(а):
Новичку, открывшему тему -
У меня, кстати, и имя есть... И твоя лень посмотреть на него, уважаемый Core2Duo, воспринимается как-то... безрадостно. ;(
Core2Duo сказал(а):
Автоиту параллельно (||) что ты пишеш INI-данные не в фаил с расширением INI. пиши хоть в EXE или BIN , всё равно, AutoIt при чтении открывает фаил как RAW, то есть "как будто блокнотом" ...
Это было БЫ так - если забыть о специфическом формате ini-файла, где, вроде как, должен быть заголовок ([в квадратных скобках]) и ещё + обязательная нумерация строк...
Core2Duo сказал(а):
Да, вроде бы, пока как-то не за что... ;)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Core2Duo
[warn title=Предупреждение]За нарушение правил форума пункт В.8:

8. Так как эта конференция называется "Русское сообщество AutoIt", язык общения на ней - Русский. Названия фирм или программных продуктов, аббревиатуры и т.д. должны быть написаны так, как они пишутся в оригинале, например не следует писать УСБ вместо USB. На форуме крайне не рекомендуется намеренно искажать русский язык и использовать "сетевой жаргон" на подобии "Аффтар выпей йадау!"....
[/warn]
 
Сообщения
28
Репутация
-3
:smile:
да че ты мне про синтаксис то рассказываешь !? как будто я сам не знаю. INI еще наплевать на то, сколькими пустыми строками разделены переменные в блоке и как далеко они от блока...
 
Автор
A

akoulev

Новичок
Сообщения
169
Репутация
2
Core2Duo сказал(а):
:smile:
да че ты мне про синтаксис то рассказываешь !? как будто я сам не знаю.
Я знаю, что ты знаешь. ;) Но ты (не я! ;D) предложил обрабатывать текстовый файл, как ini-шный; а я показал, ПОЧЕМУ это невозможно. (Ибо не во всех текстовых файлах этой несчастной планеты строки пронумерованы! Ой! Один старый добрый злой знакомый сказал бы, что эта фраза - депрессивна. Тогда - так: не во всех текстовых файлах этой счастливой планеты строки пронумерованы! :D)
Core2Duo сказал(а):
INI еще наплевать на то, сколькими пустыми строками разделены переменные в блоке и как далеко они от блока...
Оно-то так, но это совершенно не приближает нас к решению проблемы... ;|
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
что-то я не понял про нумерацию строк ;D
в ини файле строки тоже не нумеруются. если только сам этим не озадачишься.
 
Автор
A

akoulev

Новичок
Сообщения
169
Репутация
2
kaster сказал(а):
в ини файле строки тоже не нумеруются. если только сам этим не озадачишься.

Вот же "век живи"... А я-то, как написал разок:
Код:
[Тирлям-тирля-лям]
1=Тра-ля-ля
2=Тур-люр-лю
...
15=Дыр-бул-шил

, так и сам начал воспринимать эту форму как стандарт. :smile:
 

ArtInt

Знающий
Сообщения
135
Репутация
18
Извиняюсь за некропостинг

CreatoR [?]
Её можно сделать
У меня возникли некоторые проблемы при использовании данной функции. Скажите - это моя ошибка или функции? Вроде параметры передаются правильные...
 

AZJIO

Меценат
Меценат
Сообщения
2,894
Репутация
1,196
ArtInt
Мой вариант

Код:
_FileDeleteLine(@ScriptDir & '\file.txt', 1)

; $sFile - путь к файл
; $iLine - количество строк обрезаемых с конца.
Func _FileDeleteLine($sPath, $iLine)
	Local $hFile, $iPos, $sText

	; Проверка входных параметров
	If Not FileExists($sPath) Then Return SetError(1) ; ошибка, путь не верный
	If Not StringIsDigit($iLine) Then Return SetError(2) ; ошибка, номер строки не является числом

	$sText = FileRead($sPath) ; чтение файла
	$iPos = StringInStr($sText, @CRLF, 1, - $iLine) ; поиск позиции переноса строки с конца текста

	If $iPos Then ; если найдено, то
		$sText = StringLeft($sText, $iPos-1) ; чтение текста слева до найденной позиции
	Else
		$sText = '' ; количество строк в файле меньше, чем задано для обрезки, поэтому обрезка под корень
	EndIf
	$hFile = FileOpen($sPath, 2) ; запись в файл
	FileWrite($hFile, $sText)
	FileClose($hFile)
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
ArtInt [?]
возникли некоторые проблемы при использовании данной функции. Скажите - это моя ошибка или функции?
Как?! :laugh:
Как я могу сказать если не знаю в чём ошибка/проблема.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Можно регулярными выражениями:
Код:
;Отсчет строк начинается с нуля.
$iLine = 1
$sData = 'Line_000' & @CRLF & 'Line_001' & @CRLF & 'Line_002'
$sLine = StringRegExpReplace($sData, '(?m)\A((?:[^\r\n]*\r?\n){'&$iLine&'}?)[^\r\n]+', '\1')
ConsoleWrite($sLine & @LF)
 

ArtInt

Знающий
Сообщения
135
Репутация
18
inververs
Твой вариант работает как надо, однако при использовании в таком контексте:

Код:
#include <file.au3>

_FileWriteLog ("1.txt","1.1"&@CRLF&"1.2"&@CRLF&"1.3")
newFileWriteLog("2.1"&@CRLF&"2.2"&@CRLF&"2.3","1.txt",4)

Func newFileWriteLog ($text,$path,$maxlines)
   
   $textlines = StringSplit (StringStripCR($text),@LF)
   $textlines = $textlines[0]
   If $textlines>$maxlines then Return 0
   If $textlines=$maxlines then 
	  FileDelete ($path)
	  _FileWriteLog ($path,$text)
	  Return 1
   EndIf
   
   _FileWriteLog($path, $text)
   $FileLines = _FileCountLines ($path)

   If $FileLines>$MaxLines then
	  msgbox ("","","В файле записано "&$filelines&" строк, а максимально возможно - "&$maxlines&". Поэтому, строчки с "&1&"-й по "&($filelines-$maxlines)&"-ю будут удалены!")
	  For $i = 1 to $filelines-$maxlines
		 _FileDeleteLine ($path,$i)
		 msgbox ("","","В файле теперь "&_FileCountLines ($path)&" строк, ведь удалена "&$i&"-я.")
	  Next
   EndIf
   
EndFunc





Func _FileDeleteLine($sPath, $iLine)
     Dim $sData
	 $file = FileOpen ($sPath)
	 Do
		$sData&=@CRLF&FileReadLine ($file)
		 $error = @error
	  Until $error=-1
	 
	 
     $sLine = StringRegExpReplace($sData, '(?m)\A((?:[^\r\n]*\r?\n){'&$iLine&'}?)[^\r\n]+', '\1')
	 
	  FileDelete ($spath)
	  FileWriteLine ($spath,$sLine)
	  Return 1
EndFunc


Скрипт виснет намертво. Видимо проблема с записью в файл, но почему?


Добавлено:
Сообщение автоматически объединено:

CreatoR
Так-то я дал ссылку на пример в теме...
Вместо 1-й и 2-й строки удаляет 1-ю и 3-ю. При этом параметры именно 1 и 2.

AZJIO
У Вас нумерация строк с конца? 0_о
 

AZJIO

Меценат
Меценат
Сообщения
2,894
Репутация
1,196
ArtInt [?]
AZJIOУ Вас нумерация строк с конца? 0_о
Да. Я исходил из названия заголовка темы. Как можно удалять по номеру строки если неизвестно сколько строк в файле. Какая будет последняя? Если считать количество строк это работает медленнее, чем просто удалить последнюю строку.
Даже если бы пришлось вырезать строку по номеру, всё равно бы использовал StringInStr : ищем перенос строки по номеру, от полученной позиции ищем второй перенос строки, потом склеиваем левую и правую часть, это всё же должно быстрей работать, чем склеивать множество раз в цикле.
Регулярное выражение думаю тоже быстро отработает.


Скрипт виснет намертво
а почему FileOpen не закрывается функцией FileClose?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Если нужно удалить последнюю строку. Именно удалить а не затереть, то вот регулярное выражение:
Код:
$sData = 'Line_000' & @CRLF & 'Line_001' & @CRLF & 'Line_002'
$sLine = StringRegExpReplace($sData, '(?:^|\r\n)[^\r\n]*\Z', '')
ConsoleWrite($sLine & @LF)
 

ArtInt

Знающий
Сообщения
135
Репутация
18
AZJIO [?]
Цитата
Скрипт виснет намертво
а почему FileOpen не закрывается функцией FileClose?
Уже дошло, как сильно я ступил, но всё равно спасибо.




Добавлено:
Сообщение автоматически объединено:

inververs

Проблема возникает - теперь строчки не удаляются, а просто добавляются новые, сверху.
Код тот же, только с FileClose. Проверил оба варианта.
 
Верх