¿Cómo esperar hasta que se complete una operación de archivo por lotes antes de redirigir toda su salida a un archivo de texto?

¿Cómo esperar hasta que se complete una operación de archivo por lotes antes de redirigir toda su salida a un archivo de texto?

Es bastante fácil redirigir la salida a un archivo de texto con extensión >. Por ejemplo:

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

O alternativamente:

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

Cualquiera de los cuales creará un archivo de texto con una lista de los números del 1 al 10.000.

Sin embargo, estos ejemplos escribirán cada línea de salida en el disco individualmente, y no me gusta la idea de 10,000 escrituras individuales en mi SSD cada vez que se ejecutan estos archivos por lotes.

Entonces, ¿hay alguna forma de que de alguna manera pueda poner en cola la salida generada de una operación en la memoria mientras está en progreso, y luego escribir toda la salida en el disco en una sola escritura al final? ¿Algún truco de redirección avanzado? ¿O tal vez alguna forma de almacenar la salida en curso en una variable, para redirigirla más tarde con echo %output%>>output.txt?

Nota: Lo anterior son sólo ejemplos, ¡no es necesario sugerir métodos alternativos para crear listas numeradas! Mi consulta es general y trata sobre redirigir la salida a un archivo de texto evitando escrituras en el disco línea por línea.

Respuesta1

Entonces, ¿hay alguna forma de que de alguna manera pueda poner en cola la salida generada de una operación en la memoria mientras está en progreso, y luego escribir toda la salida en el disco en una sola escritura al final? ¿Algún truco de redirección avanzado? ¿O tal vez alguna forma de almacenar la salida en curso en una variable, para redirigirla más tarde con echo %output%>>output.txt?

Sí definitivamente. Utilice powershell.

La belleza de PowerShell es que puedes volcar todo en una variable, matriz o diccionario y luego, al final, en una sola escritura, escribirlo por completo en el disco.

He aquí un ejemplo:

miscript.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"

Por supuesto, puedes sustituir el número completo. Todo lo que necesitas saber es esto:

# create the variable:
$output = @() 

# Add to it
$output += "something"

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

Respuesta2

Sólo inténtalo:

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

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

Nota:Los anteriores son sólo ejemplos, ¡no es necesario sugerir métodos alternativos para crear listas numeradas! Mi consulta es general y trata sobre redirigir la salida a un archivo de texto evitando escrituras en el disco línea por línea.


 >redirect_file (
      use command blocks
    )

Para redirigir completamente los resultados de la ejecución de su bat, también puede ejecutarlo y redirigir esta ejecución a un archivo final, donde una primera llamada verifica si se pasó un archivo; de lo contrario, el bat hace una segunda llamada a sí mismo ejecutándose y esta vez redirigiendo su resultado a un archivo, como este:


@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” ::

...

información relacionada