1

次の内容のOutput.txtファイルがあります。

Server1
APPNAME  MEMORY
WINDOWS  54896378
LINUX    78542
MACOS    187963

Server2
APPNAME     MEMORY
DATABASE    587412369
SCHEMA      78542
TABLESPACE  187963

Output.txt 内のすべての数値 (54896378、78542、78542 など) を検索し、それらを 1024*1024 で割るバッチ スクリプトを作成して、Newoutput.txt ファイルのメモリを BYTES で MB に変更できるようにしたいと考えています。

以下を試しましたが、欲しいものが得られませんでした:

@echo off
setlocal enabledelayedexpansion
for /F "delims= " %%a in ('findstr "[1-9][0-9]* 0"' Output.txt) do (
SET /A Result = %a / 1024*1024 > Newoutput.txt
)

EDIT1

Output.txtファイルに次のコンテンツがある場合、すべて正常に動作していますが、スクリプトは値 6621212 のみを変換していませんFreePhysicalMemory

出力.txt:

Server1
APPNAME  MEMORY
WINDOWS  54896378
LINUX    78542
MACOS    187963

FreePhysicalMemory  TotalVisibleMemorySize  
6621212                 8387172   

新しいoutput.txt:

Server1
APPNAME  MEMORY
WINDOWS  13.58
LINUX    2.45
MACOS    1.8

FreePhysicalMemory  TotalVisibleMemorySize  
6621212                 21.4          

スクリプトにどのような変更を加える必要がありますか..?

4

2 に答える 2

3
SET /A Result = %a / 1024*1024

これは %a を 1024 で割り、出力に 1024 を掛けます。これは、あなたが望むものではありません。正しい区分は次のとおりです。

SET /A Result = %a / 1024 / 1024

または、1024*1024 = 1048576 を事前計算して、

SET /A Result = %a / 1048576
于 2013-10-17T14:30:56.540 に答える
3

バッチは整数でのみ機能することに注意してください。いくつかの計算では、値が 0 MB になります。以下は、10 進数値を扱う方法の大まかな例です。

@echo off
call :Parse > Newoutput.txt
exit /b 0

:Parse
for /f "tokens=1,2" %%A in (Output.txt) do call :ToMB "%%~B" "%%~A" || echo(%%A %%B
exit /b 0

:IsNumber <String>
for /f "delims=0123456789" %%A in ("%~1") do exit /b 1
exit /b 0

:ToMB <String> <Name>
setlocal
call :IsNumber "%~1" || exit /b 1
set "Number=%~1"
set /a "Number/=1024"
set /a "Decimal=Number"
set /a "Number/=1024"
set /a "Decimal-=(Number * 1024)"
set /a "Decimal=(Decimal * 1000) / 1024"
set "Decimal=000%Decimal%"
set "Number=   %Number%"
set "Name=%~2            "
echo %Name:~0,12%%Number:~-3%.%Decimal:~-3%
endlocal
exit /b 0

  • 更新: AppName をいくつかのフォーマットと共に出力に追加しました。(その上)
  • 更新: Newoutput.txt リダイレクトの例を追加しました。(その上)
  • 更新: すべてのトークンの変換サポートが追加され、書式設定が改善されました。(下)
  • 更新: find コマンドの最初の行スキップの修正を追加しました。(下)

@echo off
call :Parse > Newoutput.txt
exit /b 0

:Parse
setlocal
for /f "tokens=1,* delims=]" %%A in ('type "Output.txt" ^|find /n /v ""') do (
    for /f "tokens=1,2" %%X in ("%%~B") do call :Convert "%%~X" "%%~Y"
    call :Blank "%%~B"
)
endlocal
exit /b 0

:Blank <String>
set "String=%~1"
if not defined String echo.
exit /b 0

:IsNumber <String>
for /f "delims=0123456789" %%A in ("%~1") do exit /b 1
if "%~1"=="" exit /b 2
exit /b 0

:Convert <String> <String>
call :Calculate "%~1" Y || call :Display "%~1" Y
call :Calculate "%~2" || call :Display "%~2"
echo.
exit /b 0

:Calculate <Number> [Pad]
call :IsNumber "%~1" || exit /b 1
set "Number=%~1"
set /a "Number/=1024"
set /a "Decimal=Number"
set /a "Number/=1024"
set /a "Decimal-=(Number * 1024)"
set /a "Decimal=(Decimal * 1000) / 1024"
set "Decimal=000%Decimal%"
set "Number=000%Number%"
call :Display "%Number:~-3%.%Decimal:~-3%" %2
exit /b 0

:Display <String> [Pad]
set "String=%~1"
set "Pad=%~2"
if defined Pad set "String=%String%                        "
if defined String set /p "=%String:~0,24%" <nul
exit /b 0

  • 更新: 最大 2^64 の値を処理するために PowerShell を Calculate ルーチンに追加しました (以下)。

:Calculate <Number> [Pad]
call :IsNumber "%~1" || exit /b 1
set "Number="
set "Decimal="
for /f "tokens=1,2 delims=." %%A in ('"PowerShell %~1 / ( 1024 * 1024 )"') do (
    set "Number=%%A"
    set "Decimal=%%B000"
)
call :Display "%Number%.%Decimal:~0,3%" %2
exit /b 0
于 2013-10-17T14:46:13.800 に答える