出力全体をテキスト ファイルにリダイレクトする前に、バッチ ファイル操作が完了するまで待機するにはどうすればよいですか?

出力全体をテキスト ファイルにリダイレクトする前に、バッチ ファイル操作が完了するまで待機するにはどうすればよいですか?

を使用して出力をテキスト ファイルにリダイレクトするのは簡単です>。例:

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 までの数字をリストしたテキスト ファイルが作成されます。

ただし、これらの例では、出力の各行がディスクに個別に書き込まれるため、これらのバッチ ファイルが実行されるたびに SSD に 10,000 回の個別の書き込みが行われると考えるのは好ましくありません。

では、操作の進行中に、その操作で生成された出力をメモリ内でキューに入れておき、最後に出力全体を 1 回の書き込みでディスクに書き込む方法はあるでしょうか? 高度なリダイレクト トリックでしょうか? あるいは、進行中の出力を変数に格納して、後で echo でリダイレクトする方法はあるでしょうか%output%>>output.txt?

注記上記は単なる例であり、番号付きリストを作成するための代替方法を提案する必要はありません。私の質問は一般的なもので、行ごとのディスク書き込みを回避しながら出力をテキスト ファイルにリダイレクトすることに関するものです。

答え1

では、操作の進行中に、その操作で生成された出力をメモリ内でキューに入れておき、最後に出力全体を 1 回の書き込みでディスクに書き込む方法はあるでしょうか? 高度なリダイレクト トリックでしょうか? あるいは、進行中の出力を変数に格納しておき、後で echo %output%>>output.txt でリダイレクトする方法はあるでしょうか?

はい、もちろんです。PowerShell を使用してください。

PowerShell の優れた点は、すべてを変数、配列、または辞書にダンプし、最後に 1 回の書き込みですべてをディスクに書き込むことができることです。

次に例を示します。

myscript.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 を実行してこの実行を最終ファイルにリダイレクトすることもできます。最初の呼び出しでファイルが渡されたかどうかを確認し、渡されなかった場合は、bat は 2 回目の呼び出しを実行して、今度はその結果をファイルにリダイレクトします。次のようになります。


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

...

関連情報