Parse simple JSON string in Batch

后端 未结 5 1886
执笔经年
执笔经年 2020-12-16 00:36

How do you parse a simple JSON string in Batch?

For example, if I have the following JSON string:

{ \"...\":\"...\", \"year\": 2016, \"time\": \"05:01\

相关标签:
5条回答
  • 2020-12-16 00:55

    There are different ways, here's one.

    @echo off
    set string={ "year": 2016, "time": "05:01" }
    set string=%string:"=%
    
    for /f "tokens=3,5" %%a in ('echo %string%') do set d=%%a&set t=%%b
    echo -%d%- -%t%-
    pause & goto :EOF
    

    and here's a second:

    @echo off
    set string={ "year": 2016, "time": "05:01" }
    
    for /f "tokens=3,5" %%a in ('echo %string%') do set d=%%~a&set t=%%~b
    echo -%d%- -%t%-
    pause & goto :EOF
    
    0 讨论(0)
  • 2020-12-16 01:01
    @echo off
    setlocal
    
    set string={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" }
    
    rem Remove quotes
    set string=%string:"=%
    rem Remove braces
    set "string=%string:~2,-2%"
    rem Change colon+space by equal-sign
    set "string=%string:: ==%"
    rem Separate parts at comma into individual assignments
    set "%string:, =" & set "%"
    
    echo other="%other%"
    echo year="%year%"
    echo value="%value%"
    echo time="%time%"
    

    Output:

    other="1234"
    year="2016"
    value="str"
    time="05:01"
    

    A small inconvenient of this method is that "time" Batch dynamic variable will be replaced by the new JSON one, but if you use setlocal command, this point don't cause any problem.

    EDIT: Just to complete cz3ch's request of put results into "string" array instead of placing them inside individual variables:

    @echo off
    setlocal
    
    set string={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" }
    
    rem Remove quotes
    set string=%string:"=%
    rem Remove braces
    set "string=%string:~2,-2%"
    rem Change colon+space by "]equal-sign"
    set "string=%string:: =]=%"
    rem Separate parts at comma into individual array assignments
    set "string[%string:, =" & set "string[%"
    
    set string[
    
    0 讨论(0)
  • 2020-12-16 01:05

    Here's a hybrid Batch + PowerShell solution. The PowerShell objectifies (deserializes) the JSON text and outputs it in key=value format to be captured and set as batch variables by the batch for /f loop. Save this with a .bat extension and give it a shot.

    <# : batch portion (contained within a PowerShell multi-line comment)
    @echo off & setlocal
    
    set "JSON={ "year": 2016, "time": "05:01" }"
    
    rem # re-eval self with PowerShell and capture results
    for /f "delims=" %%I in ('powershell "iex (${%~f0} | out-string)"') do set "%%~I"
    
    rem # output captured results
    set JSON[
    
    rem # end main runtime
    goto :EOF
    
    : end batch / begin PowerShell hybrid code #>
    
    add-type -AssemblyName System.Web.Extensions
    $JSON = new-object Web.Script.Serialization.JavaScriptSerializer
    $obj = $JSON.DeserializeObject($env:JSON)
    
    # output object in key=value format to be captured by Batch "for /f" loop
    foreach ($key in $obj.keys) { "JSON[{0}]={1}" -f $key, $obj[$key] }
    

    Then if you want only the year and time values, just use %JSON[year]% or %JSON[time]%.

    If you're reading your JSON from a .json file, you could have the PowerShell portion read the file, replacing ($env:JSON) with ((gc jsonfile.json)). Then you wouldn't be dependent at all on whether your JSON is multi-line and beautified or minified. It'll be deserialized all the same either way.


    If execution speed is a concern, you might prefer a Batch + JScript hybrid solution. It deserializes the JSON into an object the same as the PowerShell solution, but invoking JScript from a Batch context is faster than invoking a PowerShell command or script from Batch.

    @if (@CodeSection == @Batch) @then
    @echo off & setlocal
    
    set "JSON={ "year": 2016, "time": "05:01" }"
    
    rem // re-eval self with JScript interpreter and capture results
    for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0"') do set "%%~I"
    
    rem // output captured results
    set JSON[
    
    rem // end main runtime
    goto :EOF
    
    @end // end Batch / begin JScript hybrid code
    
    var htmlfile = WSH.CreateObject('htmlfile'),
        txt = WSH.CreateObject('Wscript.Shell').Environment('process').Item('JSON');
    
    htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
    var obj = htmlfile.parentWindow.JSON.parse(txt);
    htmlfile.close();
    
    for (var i in obj) WSH.Echo('JSON[' + i + ']=' + obj[i]);
    

    And as is the case with the first PowerShell hybrid solution, you can parse multi-line JSON by reading the .json file from within the JScript portion if you wish (by creating a Scripting.FileSystemObject object and calling its .OpenTextFile() and .ReadAll() methods).


    Here's another pure batch solution, but one which sets key=value pairs as an associative array to avoid stomping on %time% as Aacini's solution does. I really think it's better to parse JSON as an object in a helper language rather than as flat text in pure batch, but I also realize that the best answer is not always the most popular.

    @echo off
    setlocal
    
    set "JSON={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" }"
    
    set "JSON=%JSON:~1,-1%"
    set "JSON=%JSON:":=",%"
    
    set mod=0
    for %%I in (%JSON%) do (
        set /a mod = !mod
        setlocal enabledelayedexpansion
        if !mod! equ 0 (
            for %%# in ("!var!") do endlocal & set "JSON[%%~#]=%%~I"
        ) else (
            endlocal & set "var=%%~I"
        )
    )
    
    set JSON[
    
    0 讨论(0)
  • 2020-12-16 01:06

    with jsonextractor.bat:

    for /f "tokens=* delims=" %%a in ('jsonextractor.bat simple.json year') do set "year=%%~a"
    
    for /f "tokens=* delims=" %%a in ('jsonextractor.bat simple.json time') do set "time_=%%~a"
    
    echo %year% -- %time_%
    
    0 讨论(0)
  • 2020-12-16 01:09

    Use https://stedolan.github.io/jq/, no need to use powershell or string manipulations in batch.

    Example to get value of field from json string:

    set "year={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" } | jq .year"
    
    echo %year%
    

    gives you 2016

    0 讨论(0)
提交回复
热议问题