Parsing a simple JSON string in a package

How do you parse a simple JSON string in a package?

For example, if I have the following JSON line:

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

There are several elements in this JSON line, and two of them are β€œyear” and β€œtime”. From this line I want to extract the values ​​for "year" and "time" in two variables without using any external libraries (i.e. I do not want to install any external utilities for downloading for this, the newly installed Windows should have all the necessary tools for this).

+9
source share
4 answers

It offers a hybrid Batch + PowerShell solution. PowerShell objectifies (deserializes) the JSON text and displays it in the format key = value, which should be captured and set as batch variables in a batch for /f loop. Save this with the .bat extension and take a picture.

 <# : 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 year and time values, just use %JSON[year]% or %JSON[time]% .

If you are reading JSON from a .json file, you can read the PowerShell part by replacing ($env:JSON) with ((gc jsonfile.json)) . Then you will not be completely dependent on whether your JSON is multi-line, embellished or miniature. It will still deserialize.


If execution speed is a problem, you might prefer the Batch + JScript hybrid solution. It deserializes JSON in an object in the same way as a PowerShell solution, but calling JScript from a batch processing context is faster than calling a PowerShell command or script from a package.

 @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]); 

As with the first hybrid PowerShell solution, you can parse multi-line JSON by reading the .json file from the JScript part if you want (by creating a Scripting.FileSystemObject and calling it .OpenTextFile() and .ReadAll() ).


Here's another clean batch solution, but one that sets the key = value pairs as an associative array to avoid stomping %time% , as the Aacini solution does. I really think that it is better to parse JSON as an object in the auxiliary language, and not as clear text in a clean batch, but I also understand 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[ 
+10
source
 @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 minor inconvenience of this method is that the dynamic variable "time" will be replaced with the new JSON, but if you use the setlocal command, this point does not cause any problems.

+8
source

There are different ways, here is 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 is the 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 
+5
source

Use https://stedolan.imtqy.com/jq/ , there is no need to use PowerShell or string manipulation in batch mode.

An example of getting a field value from a json string:

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

gives you 2016

0
source

Source: https://habr.com/ru/post/1246305/


All Articles