1

I am calling a curl command in a batch file. The request gives me a JSON response. I store that JSON response in the file. I want to know how do I parse this JSON and fetch a specific attributes?

test.bat

%comspec% /c curl -L -c cookie -b cookie -X POST -H "Accept: application/json" -s -d "{\"id\":\"123456789\",\"part\":\"part\",\"duration\":1400}" https://abcd.com > MyIP.txt
set /p string1=<MyIP.txt

Above works fine and store the JSON in a file. A dummy response looks like the following:

{"aki":"abcd", "assumed":"cdef", "expiration":12345, "sa":"temp/abcdefgh", "st":"abcd+/00'nget"}

I need to get 'aki' and 'sa' variables from this response and store them to an another file.

miserable
  • 697
  • 1
  • 12
  • 31
  • I need a bat solution. I tried one met honed in the thread you shared, but the output is coming as empty: `@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 "%"` – miserable Apr 10 '21 at 02:49
  • `cmd` does not have any modules that can encode or decode json. It can be done in pure batch, but it will be a hack and the results can vary if the json suddenly changes content. – Gerhard Apr 10 '21 at 05:42

2 Answers2

2

I tried one met honed in the thread you shared, but the output is coming as empty:

This is exactly the reason why it's inadvisable to do this in pure cmd/Batch without the proper tools.

While the code and JSON in your comment does work...

ECHO %other% %year% %value% %time%
1234 2016 str 05:01

...one of the things that will get you into trouble is the single quote within your original JSON response ("abcd+/00'nget"). You'll have to escape all the necessary characters to make this work. A tool like that properly handles JSON can show you:

ECHO {"aki":"abcd","assumed":"cdef","expiration":12345,"sa":"temp/abcdefgh","st":"abcd+/00'nget"} | ^
  xidel - -se "string:=$json" --output-format=cmd
SET string={^"aki^": ^"abcd^"^, ^"assumed^": ^"cdef^"^, ^"expiration^": 12345^, ^"sa^": ^"temp/abcdefgh^"^, ^"st^": ^"abcd+/00'nget^"}

So the following could work:

SET string={^"aki^": ^"abcd^"^, ^"assumed^": ^"cdef^"^, ^"expiration^": 12345^, ^"sa^": ^"temp/abcdefgh^"^, ^"st^": ^"abcd+/00'nget^"}
SET string=%string:"=%
SET "string=%string:~1,-1%"
SET "string=%string:: ==%"
SET "%string:, =" & set "%"

ECHO %aki% %sa%
abcd temp/abcdefgh

BUT instead I would recommend using right from the start:

xidel -s ^
-H "Cookie: [...]" -H "Accept: application/json" ^
-d "{{\"id\":\"123456789\",\"part\":\"part\",\"duration\":1400}}" ^
https://abcd.com ^
-e "$json" -e "$json/(aki,sa)"
{
  "aki": "abcd",
  "assumed": "cdef",
  "expiration": 12345,
  "sa": "temp/abcdefgh",
  "st": "abcd+/00'nget"
}
abcd
temp/abcdefgh

(not 100% sure as I can't test this obviously)

Reino
  • 3,203
  • 1
  • 13
  • 21
  • There is no need to escape all the quotes and commas in `SET string={^"aki^": ^"abcd^"^, …}`. Anyway, I like your batch file approach, although it is worth to mention that this only works when the JSON data appears exactly as stated and that it does not work with arbitrary strings; if there are more or less white-spaces (like `"aki":"abcd"`, `"aki" :"abcd"`, `"aki" : "abcd"`, etc., or line-breaks), or if `: ` or `, ` occurs in the data as well, it will fail… – aschipfl Apr 15 '21 at 12:46
  • @aschipfl This is actually @PKJ his [own approach](https://stackoverflow.com/questions/67030114/parse-json-in-bat-file#comment118483599_67030114). I wouldn't encourage parsing JSON this way! _"There is no need to escape all the quotes and commas"_ - Maybe not for his approach, but the commas definitely need to be escaped if you're going to use dedicated tools like `xidel` or `jq`. In fact, they need to be double escaped. See [my gist](https://gist.github.com/Reino17/866486cde8dae9cc30abb83b382ca4a2) for a more in-depth analysis. – Reino Apr 16 '21 at 15:21
  • Yes, I agree, I would not recommend a pure batch method either. I quickly visited the link you provided: the escaping is not necessary because of the tools you mention, it is needed due to the way you deliver the JSON string to it, namely the pipe in `echo %JSON% | xidel …`; the pipe implicitly initiates a new `cmd` instance, because `echo` is a `cmd`-internal command; – aschipfl Apr 16 '21 at 20:03
  • since normal or immediate expansion (`%JSON%`) happens before special characters and therefore escaping becomes recognised, the first level of escaping is necessary; the second one is needed because the already expanded literal string is echoed within the new `cmd` instance; however, if you would use `cmd /V /C echo(!JSON!| xidel …` instead, no escaping was necessary any more, because a new `cmd` instance is explicitly initiated with [delayed variable expansion](https://ss64.com/nt/delayedexpansion.html) enabled (`/V`); – aschipfl Apr 16 '21 at 20:04
  • special characters and therefore escaping is already processed before delayed expansion (`!JSON!`) happens, and assuming delayed expansion is disabled for the parent `cmd` instance (which is the default), variable expansion happens in the new `cmd` instance, which inherits the environment and so the variable `JSON`). Refer to [How does the Windows Command Interpreter (CMD.EXE) parse scripts?](https://stackoverflow.com/q/4094699) for more details… – aschipfl Apr 16 '21 at 20:04
  • @aschipfl I'm not a `cmd`/Batch expert, so my wording might not always be correct. The escaping is indeed necessary because of the 2nd expansion of `%json%` in `ECHO %json% | xidel …`. That's what I meant. I couldn't agree more with you. The fact that delayed expansion is disabled by default is probably also the reason why `xidel`'s author decided to double escape the special characters with `--output-format=cmd`. – Reino Apr 16 '21 at 22:37
1

Taking account of Gerhard's comment, here is a hack designed to work only with the content in your submitted MyIP.txt:

@For /F "Delims==" %%G In ('"(Set $) 2>NUL"') Do Set "%%G="
@For /F "UseBackQ Tokens=1 Delims={}" %%G In ("MYIP.txt") Do @For %%H In (%%G
 ) Do @For /F Tokens^=1-2^ Delims^=:^" %%I In ("%%~H") Do @Set "$%%I=%%J"
@(Set $ 2>NUL) && Pause

The last line will simply show you all of the variables it defined, (which is supposed to be each of your key pairs).

If you wanted only to show/use just two of them, in this case aki and sa, then the last line could be changed accordingly:

@For /F "Delims==" %%G In ('"(Set $) 2>NUL"') Do Set "%%G="
@For /F "UseBackQ Tokens=1 Delims={}" %%G In ("MYIP.txt") Do @For %%H In (%%G
 ) Do @For /F Tokens^=1-2^ Delims^=:^" %%I In ("%%~H") Do @Set "$%%I=%%J"
@Echo %$aki% & Echo %$sa% & Pause
Compo
  • 36,585
  • 5
  • 27
  • 39