0

I would like to parse config.json file and gets some specific values into variables.

Following command is working, it print value from json: type config.json | "jq-win64.exe" .path.editor

Question is how to get this value into some variable ?

I tried this, but is not working: set editorPath = type config.json | "jq-win64.exe" -r .path.editor

Result is that %editorPath% is empty

Maybe it's related to jq library (https://stedolan.github.io/jq/) but I am quite noob in windows shell so maybe someone can help how to solve this issue.

Thanks

Jurosh
  • 6,984
  • 7
  • 40
  • 51
  • 1
    You might find [this answer](http://stackoverflow.com/a/31701650/1683264) useful. Since your JSON is formatted properly, remove the braces from the `eval` line, and `echo editor: !editor!` – rojo Sep 15 '15 at 11:57
  • 1
    In general, when you want to capture the output of a command to a variable, use a `for /F` loop. `for /f "delims=" %%I in ('command') do set "variable=%%I"` or similar. See `help for` in a cmd console for more info. – rojo Sep 15 '15 at 12:00
  • If one of the answers below was helpful, please consider choosing one to mark as accepted. [See this page](http://meta.stackexchange.com/questions/5234/) for an explanation of why this is important. – rojo Sep 16 '15 at 11:39

3 Answers3

2

In general, when you want to capture the output of a command to a variable, use a for /F loop. for /f "delims=" %%I in ('command') do set "variable=%%I" or similar. See help for in a cmd console for more info.


It is possible to make JScript interpret JSON similar to the way JavaScript would. There are security concerns; but if you can be reasonably certain no one is likely to insert malicious code into the JSON, you can parse it without requiring 3rd party tools.


This example script combines the two ideas mentioned above -- invoking a JScript code block with cscript.exe, and capturing its output with a for /f loop.

config.json:

{ "path" : { "editor" : "...value..." } }

parseJSON.bat:

@if (@CodeSection == @Batch) @then

@echo off
setlocal

set "JSONfile=config.json"

for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0" "%JSONfile%"') do set "%%~I"

rem // Delayed expansion prevents path names with symbols (& or %) from choking the script
setlocal enabledelayedexpansion
echo editor: !editor!
endlocal

goto :EOF

@end // end batch / begin JScript chimera

var fso = WSH.CreateObject('scripting.filesystemobject'),
    JSONfile = fso.OpenTextFile(WSH.Arguments(0), 1);

eval('obj = ' + JSONfile.ReadAll());
JSONfile.Close();

function walk(tree) {
    for (var i in tree) {
        if (typeof tree[i] === 'object') walk(tree[i]);
        else WSH.Echo(i + '=' + tree[i]);
    }
}

walk(obj);

Output:

editor: ...value...

Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
  • Thanks this helped me to quite understand issue.. Now I have something like: ``for /f "delims=" %%I in ('readConfig .path.to.something') do set PathToSomething=%%I`` and it seem to be doing what I needed. readConfig is only doing output of jq commands... – Jurosh Sep 16 '15 at 16:44
0

Here are illustrations of two approaches using jq:

@echo off
setlocal

for /f "delims=" %%I in ('jq -n -r "\"123\""') do set A=%%I
echo A is %A%

jq -n -r  "@sh \"set B=123\"" > setvars.bat
call .\setvars.bat
echo B is %B%

In the first example, the batch file determines the variable name; in the second example, the jq program determines the variable name(s).

By the way, for non-Windows users, there is a "recipe" about this in the jq Cookbook.

peak
  • 105,803
  • 17
  • 152
  • 177
0

This is very easy for Xidel.

Dot notation:

xidel -s config.json -e "($json).path.editor"

XPath notation:

xidel -s config.json -e "$json/path/editor"

or even shorter

xidel -s config.json -e "$json//editor"

Export value to "editorPath" variable:

FOR /F "delims=" %A IN ('xidel -s config.json -e "editorPath:=$json//editor" --output-format^=cmd') DO %A
Reino
  • 3,203
  • 1
  • 13
  • 21