バッチ スクリプトを使用してテキスト ファイルを JSON ファイルに変換する

バッチ スクリプトを使用してテキスト ファイルを JSON ファイルに変換する
@echo off
setlocal EnableDelayedExpansion


echo { >>post.json
FOR /F "tokens=1,2 skip=1  delims==" %%a in (hardware.txt) do (
    set temp=%%a
    set res=%%b
    call :Trim result !res!
    call :Trim tem !temp!
    for /f "delims=0123456789" %%i in ("!result!") do (
        set var=%%i
        echo !var!
        if defined var (
            echo "!tem!" : "!result!", >> post.json
        ) else (
            echo "!tem!" : !result!, >> post.json
        ) 
    )
)
echo } >> post.json

:Trim
SetLocal EnableDelayedExpansion
set Params=%*
for /f "tokens=1*" %%a in ("!Params!") do EndLocal & set %1=%%b
exit /b

次の形式の情報を持つ hardware.txt というファイルから読み取る for ループを作成しました。

os = Microsoft Windows 10 Pro  
osVersion = 10.0.19042  
username = desktop-ujer9ka\arron 
brand = ASUSTeK COMPUTER INC.  
model = X556UR  
ram = 12  
storage = 934 
macAddress = 00:FF:F7:29:ED:06 

次の形式の json を取得します。

{ 
"os" : "Microsoft Windows 10 Pro" ,
"osVersion" : "10.0.19042" ,
"username" : "desktop-ujer9ka\arron" ,
"brand" : "ASUSTeK COMPUTER INC." ,
"model" : "X556UR" ,
"macAddress" : "00:FF:F7:29:ED:06" ,
"processor" : "Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz" ,
}

2 番目の for ループでは、else 条件は実行されません。他の簡単な方法があれば教えてください。または、誰かがこの件について手伝ってくれると助かります。JSON に数値が必要なので、変数が数値かどうかをチェックしたいので、2 番目の for ループが必要です。また、適切な json を作成するために、文字列の後の最後のコンマを削除する方法もわかりません。

答え1

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

setlocal EnableDelayedExpansion 

for /f %%N in ('find /c "=" ^<.\hardware.txt')do set "_n=%%~N" && (
   for /l %%L in (1,1,%%~N)do set /p _line_%%~L=)<.\hardware.txt

%:^(
for /L %%L in (1 1 %_n%)do for %%G in ("     ","    ","   ","  ")do set "_line_%%~L=!_line_%%~L:%%~G=!"
for /L %%L in (1 1 %_n%)do if "!_line_%%~L:~-1!"==" " (set "_line_%%~L=!_line_%%~L:~0,-1!" & goto %:^()

for /L %%L in (1 1 %_n%)do for /f usebackq^tokens^=1-2*delims^=^= %%i in (`
    call echo\!_line_%%~L!`)do set "_line_%%~L="%%~i@%%~j""

>>.\post.json (
    for /L %%L in (2 1 %_n%)do if %%~L equ 2 (
        echo\^{
        echo\    !_line_%%~L: @ =" : "!,
       )else if %%~L neq %_n% (
        echo\    !_line_%%~L: @ =" : "!,
       )else (
        echo\    !_line_%%~L: @ =" : "!
        echo\^}
       )
    ) && endlocal

検討中です:

  1. For /Fループ コマンドが を使用しているため、hardware.txt ファイルの最初の行をスキップする必要があります。skip=1ループはではなくFor /L から開始され、ファイルの行/変数も「スキップ」されます。21

  2. ハードウェア ファイル内の文字列のほとんどは、コマンドのように使用したと思われるスクリプトによって取得されwmic、ファイルにリダイレクトされました。その結果、行末の余分なスペースが行/文字列の末尾に追加されるようになりました。

  3. 数字を識別したい/識別する必要がある場所で何をする必要があるのか​​理解できませんでした(私の限られた英語の失敗)。追加の説明があれば、この時点でも回答があなたに合うように調整される可能性があります。

  4. コマンドはを使用して取得されたと既に想定していますがwmic、最初の行にジャンプするコンテンツやその起源もわからないため、hardware.txtファイルに似た情報を取得する別のbatを追加していますが、出力はすでに.jsonファイル形式でリダイレクトされています。

  5. アイテム4.確かにあなたの質問のその部分には答えていません他に簡単な方法があれば教えてください申し訳ありませんが、将来の編集/改作の取り扱いを容易にするために、いくつかのことをやり直したいです

  6. find "="最初のループで使用する場合For /F、「=」を含む行を数え、質問に投稿された hardware.txt と同等のファイルを考慮/使用しています。したがって、質問に投稿された同じ行とそれぞれの行数でテストすることをお勧めします。違いがある場合はお知らせください...

  7. 項目で指摘されている用途は6.時代遅れ/非生産的になる可能性があるskip=1 ため、以下に完全なコードと、行末に追加のスペースのない文字列を取得するための提案コードを追加します...


  • skip=1inループがない場合For:
:: for /L %%L in (2 1 %_n%)do if %%~L equ 2 ()else if()else()...
::                ↓                       ↓
:: for /L %%L in (1 1 %_n%)do if %%~L equ 1 ()else if()else()...

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

if not defined _fjson (call setlocal EnableDelayedExpansion
     set "_fjson=post.json" & call "%~f0" >"%~dp0\!_fjson!"
     timeout /t 05 | type "!_fjson!" & endlocal & goto :eof
    );= else <con call set "_spc="     ","    ","   ","  ""
     
for /f %%N in ('find /c "=" ^<.\hardware.txt')do set "_n=%%~N" & (
     for /l %%L in (1,1,%%~N)do set /p _line_%%~L=)<.\hardware.txt
 
%:^(
for /L %%L in (1,1,%_n%)do for %%G in (;%_spc%)do (set "_line_%%~L=!_line_%%~L:%%~G=!"
     if "!_line_%%~L:~-1!"==" " call set "_line_%%~L=!_line_%%~L:~0,-1!" && goto %:^()
 
for /L %%L in (1,1,%_n%)do for /f usebackq^tokens^=1-2*delims^=^= %%i in (
    `call echo\!_line_%%~L!`)do call set "_line_%%~L=    "%%~i@%%~j"" && (
         if %%~L equ 1 (echo\^{&& <con: call echo\!_line_%%~L: @ =" : "!^
            )else if not %%~L equ %_n% (call echo\!_line_%%~L: @ =" : "!^,
            )else call echo\!_line_%%~L: @ =" : "! && echo\^});=

  • 文字列をフォーマットに従って取得し.json、行末に余分なスペースを入れない
@echo off && setlocal EnableDelayedExpansion 

:: var line_1 ::  os = Microsoft Windows 10 Pro
title <nul & title set variable line_1
for /f usebackq^tokens^=4delims^=^<^> %%i in (`
     wmic os get caption /format:xml ^| find "VALUE"
   `)do set "_line_1="os" : "%%~i""

:: var line_2 :: osVersion = 10.0.19042
title <nul & title set variable line_2
for /f usebackq^tokens^=4delims^=^<^> %%i in (`
     wmic os get version /format:xml ^| find "VALUE"
   `)do set "_line_2="osVersion" : "%%~i""

:: var line_3 :: username = desktop-ujer9ka\arron 
title <nul & title set variable line_3
for /f usebackq^tokens^=4delims^=^<^> %%i in (`
     wmic /node:. computersystem get username /format:xml ^| find "VALUE"
   `)do set "_line_3="username" : "%%i""

:: var line_4 :: brand = ASUSTeK COMPUTER INC.
title <nul & title set variable line_4
for /f usebackq^tokens^=4delims^=^>^< %%i in (`
     wmic csproduct get vendor /format:xml ^| find "VALUE"
   `)do set "_line_4="brand" : "%%~i""

:: var line_5 :: model = X556UR
title <nul & title set variable line_5
for /f usebackq^tokens^=4delims^=^>^< %%i in (`
     wmic csproduct get name /format:xml ^| find "VALUE"
   `)do set "_line_5="model" : "%%~i""

:: var line_6 :: ram = 12
title <nul & title set variable line_6
for /f usebackq^tokens^=4delims^=^>^< %%i in (`
     wmic computersystem get totalphysicalmemory /format:xml ^|find "VALUE"`)do for /f %%G in ('
     mshta "vbscript:Execute("createobject(""scripting.filesystemobject""^).GetStandardStream(1^).write(Round(%%i/1073741824^)^):close")"^|more
   ')do set "_line_6="ram" : "%%~G""

:: var line_7 :: storage = 934
title <nul & title set variable line_7
for /f usebackq^tokens^=4delims^=^>^< %%i in (`
     wmic logicaldisk where Caption^="C:" get Size /format:xml^|find "VALUE"`)do for /f %%G in ('
     mshta "vbscript:Execute("createobject(""scripting.filesystemobject""^).GetStandardStream(1^).write(Round(%%i/1073741824^)^):close")"^|more
   ')do set "_line_7="storage" : "%%G""

:: var line_8 macAddress = 00:FF:F7:29:ED:06
title <nul & title set variable line_8
for /f usebackq^tokens^=4delims^=^>^< %%i in (`
     wmic path Win32_NetworkAdapter where "PNPDeviceID like '%%%%PCI%%%%' and NetConnectionStatus='2' and AdapterTypeID='0'" get MacAddress /format:xml ^| find "VALUE"
   `)do set "_line_8="macAddress" : "%%~i""

:: var line_9 :: processor = Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
title <nul & title set variable line_9
for /f usebackq^tokens^=4delims^=^>^< %%i in (`
      wmic CPU get NAME /format:xml ^| find "VALUE"
    `)do set "_line_9="processor" : "%%~i""

:: var lines 1-9 :: Writing lines from 1 to 9 in post.json file
title <nul & title write line 1-9 to file: .\post.json
>.\post.json (
    for /L %%L in (1 1 9)do for /f usebackq^delims^= %%i in (`
            "echo\    !_line_%%~L!"`)do if %%~L equ 1 (
             echo\^{ && echo\%%~i,)else if %%~L neq 9 (
             echo\%%~i,)else echo\%%~i&& echo\^}
            )

:: Checking lines_1-9 :: Checking file contents/lines on screen
title <nul & title Checking file contents/lines on screen
timeout /t 10 | type .\post.json & endlocal

  • 私のコンピューターでは、次のような出力が得られます。
{
    "os" : "Microsoft Windows 10 Home Single Language",
    "osVersion" : "10.0.19043",
    "username" : "DESKTOP-JRRL1K6\DP",
    "brand" : "LENOVO",
    "model" : "80UH",
    "ram" : "20",
    "storage" : "447",
    "macAddress" : "5C:C9:D3:7E:B1:1C",
    "processor" : "Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz"
}

ここに画像の説明を入力してください

答え2

実行したとおりset var=%%、変数は定義されていますが、空です。

空の変数を確認するには:

IF [%1] == [] ...
IF "%~1" == "" ...

詳細については、投稿をご覧ください。 バッチ ファイル内のパラメーターが空かどうかをテストする適切な方法は何ですか?

関連情報