У меня есть файл, в котором есть пара 100 строк. Я хочу сохранить только часть и отказаться от остального. Сначала я создаю функцию, которая дает мне номер строки, на которой файл действительно должен заканчиваться, используя это:
for /f "tokens=1 delims=:" %%a in ('
findstr /n /c:"(search term)" "(source file location and name)"
') do set start=%%a
SET /A truestart=%start%-1
Это дает мне значение строки, которое на 1 выше искомого термина, и это именно то, что я хочу. Например. значение равно 600, поэтому строки с 1 по 599 копируются в другой файл и игнорируется строка 600 для завершения документа.
Я пытался найти решение, думая, что мне следует использовать форму цикла для копирования строк одну за другой в новый файл до тех пор, пока не будет достигнута указанная строка.
Я нашел этот цикл на этой странице, который должен делать то, что я хочу:
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION
:: set counter
set c=0
for /f "delims=|" %%i in ("source file location and name") do (
:: increment counter for each line read
set /a c=!c!+1
if !c! leq %truestart% echo %%i >> "destination file location and name"
)
Это дает мне новый файл, но он копирует в целевой файл только местоположение и имя исходного файла, а не содержимое источника.
Итак, я знаю, что мне что-то не хватает, читая источник по каждой строке, но я не могу понять, что именно.
Я также попробовал использовать больше:
more /e /p +%truestart% "source file location and name" > "destination file location and name"
Это дает мне противоположный результат: отображается только та часть, которую я хочу убрать, и не учитывается то, что я действительно хочу.
Прочтите for /?
еще раз: ваш синтаксис оценивает не содержимое файла, а литеральную строку (имя файла). См. оператор usebackq
.
Команду set можно сократить до set /a c+=1
Кроме того, в первом представленном вами примере вы могли бы упростить set start=%%a
, а затем после цикла поставить SET /A truestart=%start%-1
, используя только set /a truestart = %%a - 1
.
Спасибо за предложения. Я немного почистил его, основываясь на ваших предложениях. После небольшого исследования я нашел лучший обходной путь.
Мне удалось получить желаемый результат с помощью PowerShell:
@echo off
rem set final line
for /f "tokens=1 delims=:" %%a in ('
findstr /n /c:"(search term)" "(source document)"
') do set /a end=%%a-2
set "inputFile = "(source document)""
set "outputFile = "(destination document)""
powershell -Command "Get-Content -Path '%inputFile%' -TotalCount %end% | Set-Content -Path '%outputFile%'"
Это дает мне именно тот результат, который я хочу.
Если вы хотите, чтобы вышеизложенное было правильным, то есть чтобы PowerShell
-Command
оставалось неизменным, вы должны изменить set "inputFile = "(source document)""
и set "outputFile = "(destination document)""
на Set "inputFile=(source document)"
и Set "outputFile=(destination document)"
соответственно. В противном случае вложенные двойные кавычки разобьются на проанализированную команду, переданную powershell.exe
.
Не используйте недопустимые ярлыки в качестве идентификатора комментария. Для этого есть команда
REM
. Недопустимые метки внутри блока кода/цикла имеют тенденцию совершать неожиданные действия (например, пропуск строк).