Войти

Показать полную графическую версию : [решено] Как удалить последнюю строку в текстовом файле?


Страниц : [1] 2

ivanxam
20-02-2014, 16:03
Добрый день, люди добрые помогите, что-то я вообще запутался.
Как удалить последнюю строку в файле? Строку эту я знаю.

Файл 100001.txt

20140201.jrn
20140202.jrn
20140203.jrn
20140204.jrn
20140205.jrn
20140206.jrn
20140207.jrn
20140208.jrn
20140209.jrn
20140210.jrn


Или можно выполнить dir без последней строки(файла)

Georgio
21-02-2014, 11:56
что-то я вообще запутался »

Решить эту задачу в общем виде (т. е. и с учётом пустых строк, и без потери символов) на языке командной строки действительно сложно.


Строку эту я знаю »

А что изменится в решении, если Вы эту строку не знаете?


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

В Вашем случае так:

@echo off
for /f "usebackq" %%i in ("100001.txt") do (
set /a m+=1
)
(
for /f "usebackq delims=" %%i in ("100001.txt") do (
set /a n+=1
call echo %%n%%|>nul findstr /vxc:%m%&& echo %%i
))>.tmp
move .tmp "100001.txt">nul


Или можно выполнить dir без последней строки(файла) »

Можно ли выполнить команду "dir", чтобы в её выводе не было последней строки?

Вариант №1.

@echo off
for /f "delims=" %%i in ('dir /a-d /b *.jrn') do (
set /a m+=1
)
(
for /f "delims=" %%i in ('dir /a-d /b *.jrn') do (
set /a n+=1
call echo %%n%%|>nul findstr /vxc:%m%&& echo %%i
))>"100001.txt"

Вариант №2.

@echo off
for %%i in (*.jrn) do (
set /a m+=1
>nul dir /a-d /b %%i
)
(
for %%i in (*.jrn) do (
set /a n+=1
call echo %%n%%|>nul findstr /vxc:%m%&& dir /a-d /b %%i
))>"100001.txt"

Вариант №3.

Если в выводе нужны только имена файлов с расширениями (как у Вас), то можно обойтись без команды "dir".

@echo off
for %%i in (*.jrn) do (
set /a m+=1
)
(
for %%i in (*.jrn) do (
set /a n+=1
call echo %%n%%|>nul findstr /vxc:%m%&& echo %%i
))>"100001.txt"


P. S. Команда "@echo off" обязательна во всех приведённых кодах.

sov44
21-02-2014, 12:46
Вариант 4 @echo off

for /f "delims=" %%a in (out.txt) do set "old=%%a"
findstr /vc:"%old%" "out.txt">>new.txt

Georgio
21-02-2014, 14:07
sov44, а если в выводе команды, например, такой: for /f "tokens=*" %%i in ('dir /a-d /b /s') do echo %%~nxi, таких "%old%" будет несколько?

По этой причине я не рассматривал этот вариант.

Iska
21-02-2014, 14:25
Я бы попробовал так:
@echo off
setlocal enableextensions enabledelayedexpansion

set sSourceFile=C:\Песочница\040\100001.txt

call :GetTemporaryName

if exist "%sSourceFile%" (
for /f "usebackq delims=" %%i in (
`type "%sSourceFile%"^|find.exe /v /c ""`
) do set /a iTotalLines = %%i

set /a iNeedLines = iTotalLines - 1

>"%TemporaryName%" (
for /f "usebackq tokens=1* delims=[]" %%i in (
`type "%sSourceFile%"^|find.exe /v /n ""`
) do if %%i leq !iNeedLines! echo.%%j
)

>nul copy /y "%sSourceFile%" "%sSourceFile%.bak"
>nul copy /y "%TemporaryName%" "%sSourceFile%"
del /f /q "%TemporaryName%"
) else (
echo Source file [%sSourceFile%] not found.
exit /b 1
)

endlocal
exit /b 0
rem ==========================================================================

rem ==========================================================================
rem Функция GetTemporaryName()
rem
rem Серый форум / CMD/BAT: генерация пути для временного файла или папки
rem (http://forum.script-coding.com/viewtopic.php?id=6259)
rem ==========================================================================
:GetTemporaryName
setlocal enableextensions enabledelayedexpansion

:NextName
set sTempName=%temp%\temp%random%.tmp

if exist "%sTempName%" goto :NextName

set sProcName=%~0

endlocal & set %sProcName:~4%=%sTempName%
exit /b 0
rem ==========================================================================

ivanxam
21-02-2014, 14:42
Всем огромное спасибо.

sov44
21-02-2014, 17:26
sov44, а если в выводе команды, например, такой: »
Как удалить последнюю строку в файле? »
Georgio, т.з. сформулировано чётко.

вторую часть вопроса не рассматривал, т. к. не понятно. по какому критерию считать последнюю строку
выполнить dir без последней строки(файла) »

megaloman
21-02-2014, 18:16
Прямолинейно@Echo Off

Set "File=100001.txt"

SetLocal EnableExtensions EnableDelayedExpansion

Set /A N=0
FOR /F "usebackq delims=" %%i in (`Type "%File%"`) do Set /A N+=1

Set /A M=%N%

Set /A N=0
FOR /F "usebackq delims=" %%i in (`Type "%File%"`) do Set /A N+=1 & If !N!==1 (Echo %%i>"%File%") Else (If !N! LSS %M% Echo %%i>>"%File%")
Не очень понял насчет Dir без последней строки. Вы что, командой Dir в файл 100001.txt заносите имена файлов? А у файлов имена ГГГГММДД.JRN ? Тогда возможно более короткое решение ...

Iska
21-02-2014, 18:33
Прямолинейно »
megaloman, тут опять вопрос с пропуском пустых строк при разборе по «for /f». В данном конкретном случае (разбор «dir /b») сие, конечно, не существенно.

Вы что, командой Dir в файл 100001.txt заносите имена файлов? »
Я понял, что так.

Тогда возможно более короткое решение ... »
Выкладывайте, конечно.

megaloman
21-02-2014, 19:10
Опять прямолинейно, если в файле 100001.txt не важен порядок (по убыванию-возрастанию)@Echo Off

Set "File=100001.txt"
Set "Mask=20??????.jrn"

Del "%File%" 2>Nul
FOR /F "skip=1 usebackq delims=" %%i in (`Dir "%Mask%" /b /A:-D /O:-N 2^>nul`) Do Echo %%i>>"%File%"
Увы, если важен порядок, придётся добавить за этим приведенным кодом сортировку, что не короче предыдущего решения
SetLocal EnableExtensions EnableDelayedExpansion
Set /A N=0
FOR /F "usebackq delims=" %%i in (`Type "%File%"^|Sort`) Do Set /A N+=1 & If !N!==1 (Echo %%i>"%File%") Else (Echo %%i>>"%File%")

megaloman
21-02-2014, 19:51
Можно извратиться вот так, при этом последнее имя файла из Dir не попадёт в текстовый файл@Echo Off

Set "File=100001.txt"
Set "Mask=20??????.jrn"

SetLocal EnableExtensions EnableDelayedExpansion

Set "String='"
FOR /F "usebackq delims=" %%i in (`Dir "%Mask%" /b /A:-D /O:N 2^>nul`) Do If !String!==' (Set "String=%%i"&Del "%File%" 2>Nul) Else (Echo !String!>>"%File%"&Set "String=%%i")
Или, чтобы легче читалось, то же самое@Echo Off

Set "File=100001.txt"
Set "Mask=20??????.jrn"

SetLocal EnableExtensions EnableDelayedExpansion

Set "String='"
FOR /F "usebackq delims=" %%i in (`Dir "%Mask%" /b /A:-D /O:N 2^>nul`) Do (
If !String!==' (
Set "String=%%i"
Del "%File%" 2>Nul
) Else (
Echo !String!>>"%File%"
Set "String=%%i"
)
)

Или, если вернуться к изначальной теме "Как удалить последнюю строку в текстовом файле?", то на этой же идее@Echo Off

Set "File=100001.txt"

SetLocal EnableExtensions EnableDelayedExpansion

Set "String='"
FOR /F "usebackq delims=" %%i in (`Type "%File%"`) Do If !String!==' (Set "String=%%i"&Del "%File%" 2>Nul) Else (Echo !String!>>"%File%"&Set "String=%%i")

Georgio
21-02-2014, 20:19
"Немного экзотики"...

Использование команды "fc":

@echo off
set text_file=100001.txt
for /f %%i in ('find /c /v ""^<"%text_file%"') do set /a n=%%i-1
>nul copy nul 0.tmp
>1.tmp fc /lb%n% 0.tmp "%text_file%"
>2.tmp<1.tmp more +4
>3.tmp<2.tmp find /v "*****"
del 0.tmp 1.tmp 2.tmp
>nul move "%text_file%" "%text_file%.bak"
>nul move 3.tmp %text_file%

Жаль только, что слишком длинные строки команда "fc" располагает в несколько строк.

В случае использования только двух временных файлов в конце переписанного файла будут две лишние пустые строки:

@echo off
set text_file=100001.txt
for /f %%i in ('find /c /v ""^<"%text_file%"') do set /a n=%%i-1
>nul copy nul 0.tmp
fc /lb%n% 0.tmp "%text_file%"| more +4|>1.tmp find /v "*****"
del 0.tmp
>nul move "%text_file%" "%text_file%.bak"
>nul move 1.tmp %text_file%

Anufriev
14-09-2018, 10:05
)
Или, если вернуться к изначальной теме "Как удалить последнюю строку в текстовом файле?", то на этой же идее
@Echo Off
Set "File=100001.txt"
SetLocal EnableExtensions EnableDelayedExpansion
Set "String='"
FOR /F "usebackq delims=" %%i in (`Type "%File%"`) Do If !String!==' (Set "String=%%i"&Del "%File%" 2>Nul) Else (Echo !String!>>"%File%"&Set "String=%%i")»

День добрый, данный батник хорошо работает, если обрабатывать только один файл

вопрос, а как его подправить, что бы он обрабатывал несколько файлов?

megaloman
14-09-2018, 12:19
Anufriev, Неужели это я писал? Задача решалась применительно к конкретной ситуации (это я свою совесть успокаиваю). Боюсь, возможны косяки, если есть пустые строки и всякие спецсимволы. что бы он обрабатывал несколько файлов? » - не понимаю, что за файлы и где, как имена задаются.
Если тупо и не думать, организуем процедуру и в неё будем передавать имена файлов@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
Call :LastDel "100001.txt"
Call :LastDel "D:\тра ля ля\1200001.txt"
Call :LastDel "\\Server\Share\ogogo.ini"
GoTo :Eof

:LastDel
Set "File=%~1"
Set "String='"
FOR /F "usebackq delims=" %%i in (`Type "%File%"`) Do If !String!==' (Set "String=%%i"&Del "%File%" 2>Nul) Else (Echo !String!>>"%File%"&Set "String=%%i")
GoTo :EofНе тестировал.
Если это все файлы по какой-то маске в определённой папке, возможно организация For c тем же вызовом процедуры - уточните задачу, если надо. Опять же, работая с текстом в CMD, можно хорошо вляпаться.

YuS_2
14-09-2018, 20:20
Опять же, работая с текстом в CMD, можно хорошо вляпаться. »
Дык, почему бы не воспользоваться powershell?
$arr = dir *.txt #либо прописываем массив с конкретными файлами, имеющими различные пути и расширения.
$arr|%{$a = gc $_.fullname;$a|select -skiplast 1|sc $_.fullname}

Anufriev
15-09-2018, 06:21
Цитата megaloman:
Опять же, работая с текстом в CMD, можно хорошо вляпаться. »
Дык, почему бы не воспользоваться powershell?
$arr = dir *.txt #либо прописываем массив с конкретными файлами, имеющими различные пути и расширения.
$arr|%{$a = gc $_.fullname;$a|select -skiplast 1|sc $_.fullname}
-------
scio me nihil scire »

увы, не везде и не всегда можно использовать что-то лучше cmd:(

Не тестировал.
Если это все файлы по какой-то маске в определённой папке, возможно организация For c тем же вызовом процедуры - уточните задачу, если надо. Опять же, работая с текстом в CMD, можно хорошо вляпаться. »

простите, что не конкретно описал

файлы имеют маску *.xml
находятся в одной папке, при удалении строки копируются в другую папку
содержимое разнообразное, но всегда нужно удалить последнюю строку (подпись) она тоже меняется

p.s. может и правда отдельную тему создать, что-бы людям проще было найти (я посчитал, что можно небольшой корректировкой кода обойтись, наивный?) :)

YuS_2
15-09-2018, 13:42
увы, не везде и не всегда можно использовать что-то лучше cmd »
увы, это так.
Но что мешает стремиться к лучшему? :)

Iska
15-09-2018, 17:10
Ориентироваться на строки в xml-файлах… Я бы не стал.

Anufriev
17-09-2018, 05:08
Anufriev, дайте хотя бы один файл для примера, переименуйте его в txt и прикрепите к сообщению
Сильно сомневаюсь, что для xml »

Утро доброе, прошу

p.s. Естественно данный занулены

Iska
17-09-2018, 05:50
но всегда нужно удалить последнюю строку (подпись) она тоже меняется »
Скажите, коллега, подпись всегда одна и та же? А если могут быть разные — не попадётся ли как-нибудь однажды в подписи символ 0x0A или 0x0D, сиречь LineFeed, або CarriageReturn? Тройку нулевых символов я там уже вижу.

увы, не везде и не всегда можно использовать что-то лучше cmd »
Ну, WSH везде есть.
Option Explicit

Dim strSourceFolder

Dim objFSO
Dim objFile

Dim arrContent


If WScript.Arguments.Count = 1 Then
strSourceFolder = WScript.Arguments.Item(0)

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

If objFSO.FolderExists(strSourceFolder) Then
For Each objFile In objFSO.GetFolder(strSourceFolder).Files
If StrComp(objFSO.GetExtensionName(objFile.Name), "xml", 0) = 0 Then
With objFSO.OpenTextFile(objFile.Path)
arrContent = Split(.ReadAll(), vbCrLf)
.Close
End With

ReDim Preserve arrContent(UBound(arrContent) - 1)

objFile.Copy objFSO.BuildPath(strSourceFolder, objFSO.GetBaseName(objFile.Name) & ".bak"), True

With objFSO.CreateTextFile(objFile.Path, True)
.Write Join(arrContent, vbCrLf) & vbCrLf
.Close
End With
Else
' Nothing to do
End If
Next
Else
WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
WScript.Quit 2
End If

Set objFSO = Nothing
Else
WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source folder>"
WScript.Quit 1
End If

WScript.Quit 0
Путь к целевому каталогу указывается параметром скрипта (также можно просто перетащить папку на скрипт в Проводнике). Для каждого обработанного xml-файла создаётся резервная копия .bak.




© OSzone.net 2001-2012