Convierta un archivo de texto a un archivo json usando un script por lotes

Convierta un archivo de texto a un archivo json usando un script por lotes
@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

Hice un bucle for que lee un archivo llamado hardware.txt que tiene información en el siguiente formato:

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 

Obtengo json en el siguiente formato:

{ 
"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" ,
}

En el segundo bucle for, la condición else no se ejecuta. Si hay alguna otra manera fácil, hágamelo saber o si alguien puede ayudarme, sería genial. Necesito el segundo bucle for porque quiero comprobar si la variable es un número o no, ya que necesito un número en el json. Tampoco sé cómo eliminar la última coma después de la cadena para crear un json adecuado.

Respuesta1

@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

Estoy considerando:

  1. Debe omitir la primera línea de su archivo hardware.txt, porque su For /Fcomando de bucle está usando skip=1, por lo que el For /L bucle comienza en 2no 1, por lo que también "omitió" una línea/variable del archivo.

  2. La mayoría de sus cadenas en el archivo de hardware fueron recuperadas mediante scripts. Supongo que usé como el wmiccomando y las redirigí al archivo y, en consecuencia, aquí es donde los espacios adicionales al final de la línea se agregaron al final de las líneas/ cadena.

  3. No entendí (fallo de mi inglés limitado) qué debe hacer cuando desea/necesita identificar números. Cualquier explicación adicional puede adaptar la respuesta para adaptarse a usted en este punto también.

  4. Aunque ya asumo que sus comandos se obtuvieron mediante el uso de wmic, sin saber tampoco qué contenido saltar en la primera línea o su origen, estoy agregando otro bat que obtiene información similar a su archivo hardware.txt, sin embargo, ya redirige la salida en formato de archivo .json

  5. Artículo4.definitivamente no responde esa parte de tu preguntaSi hay alguna otra manera fácil, hágamelo saber., perdóname, algunas cosas prefiero rehacerlas para facilitar su manejo en futuras ediciones/adaptaciones

  6. Cuando lo uso find "="en el primer For /Fciclo, cuento las líneas que tienen "=" y considero/uso un archivo igual a su hardware.txt publicado en su pregunta, por lo que le sugiero que pruebe con las mismas líneas y la cantidad respectiva de líneas publicadas en la pregunta, si hay diferencias, hágamelo saber...

  7. Supongo que el uso señalado en el artículo.6.puede volverse skip=1 obsoleto/improductivo, por lo que agregaré un código completo a continuación y también el código de sugerencia para obtener las cadenas sin espacios adicionales al final de las líneas...


  • Sin bucles skip=1internos 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\^});=

  • Obtenga cadenas en .jsonformato y sin espacios adicionales al final de la línea
@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

  • En mi computadora obtengo el resultado:
{
    "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"
}

ingrese la descripción de la imagen aquí

Respuesta2

Como lo hizo set var=%%, la variable está definida, simplemente está vacía.

Para comprobar si hay una variable vacía:

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

Para más información ver la publicación. ¿Cuál es la forma correcta de probar si un parámetro está vacío en un archivo por lotes?

información relacionada