Как дождаться завершения операции с пакетным файлом, прежде чем перенаправлять весь ее вывод в текстовый файл?

Как дождаться завершения операции с пакетным файлом, прежде чем перенаправлять весь ее вывод в текстовый файл?

Достаточно просто перенаправить вывод в текстовый файл с помощью >. Например:

for /l %%n in (1,1,10000) do (echo %%n>>output.txt)

Или альтернативно:

for /l %%n in (1,1,10000) do (call:sub %%n)
exit
    
:sub
    (echo %1)>>output.txt
exit /b

Любой из этих вариантов создаст текстовый файл, содержащий числа от 1 до 10 000.

Однако эти примеры будут записывать каждую строку вывода на диск по отдельности, и мне не нравится мысль о 10 000 отдельных записей на мой SSD каждый раз при запуске этих пакетных файлов.

Итак, есть ли способ как-то вместо этого поставить в очередь сгенерированный вывод операции в памяти, пока он выполняется, а затем записать весь вывод на диск за одну запись в конце? Какой-нибудь продвинутый трюк с перенаправлением? Или, может быть, какой-то способ сохранить текущий вывод в переменной, чтобы перенаправить его позже с помощью echo %output%>>output.txt?

Примечание: Выше приведены только примеры, нет необходимости предлагать альтернативные методы создания нумерованных списков! Мой запрос носит общий характер и касается перенаправления вывода в текстовый файл, избегая при этом построчной записи на диск.

решение1

Итак, есть ли способ как-то вместо этого поставить в очередь сгенерированный вывод операции в памяти, пока он выполняется, а затем записать весь вывод на диск за одну запись в конце? Какой-нибудь продвинутый трюк с перенаправлением? Или, может быть, какой-то способ сохранить текущий вывод в переменной, чтобы перенаправить его позже с помощью echo %output%>>output.txt?

Да, определенно. Используйте powershell.

Прелесть PowerShell в том, что вы можете сохранить все данные в переменной, массиве или словаре, а затем в конце, за одну операцию записи, записать все это целиком на диск.

Вот пример:

мойскрипт.ps1:

# create the output variable that we'll write to disk later.
$output = @()

1..10000|foreach-object {
    #get the number: (this line is optional, but just to make it easier to understand)
    $number = $_

    #add the number to the output
    $output += $number
}


#print the output to the screen:
$output

#write the output to a file:

$output|out-file -FilePath "output.txt"

Конечно, вы можете заменить все число целиком. Все, что вам нужно знать, это:

# create the variable:
$output = @() 

# Add to it
$output += "something"

# Write it to disk:
$output|out-file -FilePath "output.txt"

решение2

Просто попробуй:

@echo off & cd /d "%~dp0"

>.\log.txt =;(
     for /l %%L in (1,1,10000)do echo/%%~L
    );=

Примечание:Выше приведены лишь примеры, нет необходимости предлагать альтернативные методы создания нумерованных списков! Мой запрос носит общий характер и касается перенаправления вывода в текстовый файл, избегая при этом построчной записи на диск.


 >redirect_file (
      use command blocks
    )

Чтобы полностью перенаправить результаты из выполнения вашего bat, вы также можете выполнить его и перенаправить это выполнение в конечный файл, где первый вызов проверяет, был ли передан файл, если нет, bat делает второй вызов для себя, запуская и на этот раз перенаправляя свой результат в файл, например:


@echo off && setlocal enableextensions

rem :: checks if the variable has received value :: 
if /i "!_log!/" == "/" (

   echo/Batch call started: !date! - / - !time!

   rem :: If it has not received any value, it will assign and call the bat itself 
   set "_log="%temp%\log_bat.log"" && echo/>!_log! & "%~0" >>!_log! & exit /b

   rem :: As soon as it has received some value, the bat will continue executing, already saving in: !_log!
   
   ) else endlocal

:: your current code in bat starts at that point saving the outputs in "%temp%\log_bat.log” ::

...

Связанный контент