如何以纯批处理方式解析JSon

时间:2018-07-04 19:30:51

标签: json parsing batch-file for-loop token

我试图了解批处理文件中的for循环如何使用/ F“ delims =”选项但不带令牌地遍历所有项。我尝试了各种方法,但是失败了。首先,我知道还有其他方法可以读取json文件,但我只想了解如何在不使用任何外部程序jscript jq等的情况下以纯批处理方式进行读取。JSon格式如下所示,但项目数和顺序它们趋于变化。

{"SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString"}
{"SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString"}
{"SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString"}
{"SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeString"}
etc

但有时可能只是:

"SomeVariableName2": "SomeString2", "SomeVariableName1": "SomeString1",

例如,我已经这样做了:

SetLocal DisableDelayedExpansion
For /F "delims=" %%c (file.json) Do(
REM iterate through each line
  set "Line=%%c"
  setlocal EnableDelayedExpansion
  set CR=CRLFCRLF
  Set "LineChange1=!Line:~1,-1!"
  for %%d in ("!CR!") do set LineChange2=!LineChange1:", "=%%~d!
  for %%e in (!LineChange4:CRLFCRLF= !) do set /a numtkns+=1
  REM but don't know how to insert the above numtkns in for options as it seems to require a function.
  set LineChange3=!LineChange2:": "==!
  set LineChange4=!LineChange3:"=!
  set /A Countr+=1
  REM this leaves this current line stored in variable LineChange4 as SomeVariableName=SomeStringCRLFCRLFSomeVariableName=SomeStringCRLFCRLFSomeVariableName=SomeStringCRLFCRLFSomeVariableName=SomeString
  )

或者我可以使用换行符代替CRLFCRLF:

SetLocal DisableDelayedExpansion
For /F "delims=" %%c (file.json) Do(
REM iterate through each line
set "Line=%%c"
setlocal EnableDelayedExpansion
for /f %%d in ('copy /Z "%~dpf0" nul') do (
 set "CR=%%d"
)
Set "LineChange1=!Line:~1,-1!"
for %%e in ("!CR!") do set LineChange2=!LineChange1:", "=%%~e!
set LineChange3=!LineChange2:": "==!
set LineChange4=!LineChange3:"=!
set /A Countr+=1

)

这将导致多行存储在变量LineChange4中:

SomeVariableName=SomeString
SomeVariableName=SomeString
SomeVariableName=SomeString
SomeVariableName=SomeString

如何遍历每个键值对并将每个值分配给与键名称相同的变量。我看过另一篇文章,他们确实设置了var_%SomeVariableName%= SomeString,但它仅适用于第一个键值对,并且我希望它遍历所有项直到最后一个项,即使令牌的数量及其顺序有所不同。

编辑:SomeString可能是带有各种字符的标题,因此唯一已知的值是SomeVariableName键,这些键通常没有空格。

Edit2:我最初并没有添加,我还使用了“ Set“ LineChange1 =!Line:〜1,-1!”来删除JSon文件通常附带的花括号。

3 个答案:

答案 0 :(得分:3)

另一种更简单的方法:

@echo off
setlocal EnableDelayedExpansion

rem Read the lines of JSon file, removing braces
for /F "delims={}" %%a in (file.json) do (
   set "line=%%~a"
   rem Process each pair of "variable": "string" values
   for %%b in ("!line:": "==!") do echo SET %%b
)

使用此输入文件:

{"SomeVariableName1": "Some String 1", "SomeVariableName2": "Some&String<2", "SomeVariableName3": "Some>String|3", "SomeVariableName4": "Some  String  4"}
{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}
{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}
{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}

...这是输出:

SET "SomeVariableName1=Some String 1"
SET "SomeVariableName2=Some&String<2"
SET "SomeVariableName3=Some>String|3"
SET "SomeVariableName4=Some  String  4"
SET "SomeVariableName1=SomeString1"
SET "SomeVariableName2=SomeString2"
SET "SomeVariableName3=SomeString3"
SET "SomeVariableName4=SomeString4"
SET "SomeVariableName1=SomeString1"
SET "SomeVariableName2=SomeString2"
SET "SomeVariableName3=SomeString3"
SET "SomeVariableName4=SomeString4"
SET "SomeVariableName1=SomeString1"
SET "SomeVariableName2=SomeString2"
SET "SomeVariableName3=SomeString3"
SET "SomeVariableName4=SomeString4"

答案 1 :(得分:1)

鉴于输入字符串的键(SomeVariableName)和值(SomeString)部分都不包含*?<>",它们实际上包含在引号""中,关键部分(SomeVariableName)不包含:= ,并且值部分(SomeString)不等于序列: + SPACE ,则可以执行以下操作:

@echo off
rem // Read JSON file line by line:
for /F "usebackq delims=" %%L in ("file.json") do (
    rem // Store current line string:
    set "LINE=%%L"
    setlocal EnableDelayedExpansion
    rem // Replace key/value separator `": "` by `":"` (remove space):
    set "LINE=!LINE:": "=":"!"
    rem // Trim off opening and closing braces `{`/`}`:
    if defined LINE if "!LINE:~,1!"=="{" set "LINE=!LINE:~1!"
    if defined LINE if "!LINE:~-1!"=="}" set "LINE=!LINE:~,-1!"
    rem // Iterate through key/value pairs (separated by `, `):
    for %%P in (!LINE!) do (
        endlocal
        rem // Split key/value pair:
        for /F "tokens=1* delims=: eol=:" %%Q in ("%%P") do (
            rem // Remove quotes, assign variable (key = value):
            set "%%~Q=%%~R"
        )
        setlocal EnableDelayedExpansion
    )
    endlocal
)

此方法通过删除分隔冒号"SomeVariableName": "SomeString"后面的 SPACE 来更改每个键/值对:;由于:不是标准的令牌分隔符,与 SPACE 和逗号,相对,因此标准for loop可以将每个键/值对作为一个单独的对象进行迭代项目;然后可以使用for /F loop:处拆分键和值;最后,~ modifier删除了每个部分周围的引号"",并完成了分配。

完成切换delayed expansion的目的是避免输入字符串中出现惊叹号!

答案 2 :(得分:1)

file.json或正在下载的数据的格式如下

{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}
{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}
{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}
{"SomeVariableName1": "SomeString1", "SomeVariableName2": "SomeString2", "SomeVariableName3": "SomeString3", "SomeVariableName4": "SomeString4"}

即使SomeString包含空格,下面的代码也可以按照aschipfl给出的答案修改后的代码工作。

:: Define a TAB variable
For /F "delims=" %%A In ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') Do Set "TAB=%%A"

rem // also works for ('something that downloads json content')
For /F "delims=" %%c In ('file.json') Do (
    REM // Store current line string:
    Set "LINE=%%c"
    SetLocal EnableDelayedExpansion
    REM // Replace beginning and ending curly brackets:
    Set "LineChange1=!Line:~1,-1!"
    REM // Replace key/value separator ": " by ":" (remove space):
    Set "LineChange2=!LineChange1:": "=":"!"
    REM // Replace CSV ", " with TSV "TAB" (remove space):
    Set "LineChange3=!LineChange2:", "="%TAB%"!"
    REM // Iterate through key/value pairs (separated by Tab):
    For %%P In (!LineChange3!) Do (
        EndLocal
        REM // Split key/value pair:
        For /F "tokens=1* delims=: eol=:" %%Q In ("%%P") Do (
            REM // Remove quotes, assign variable (key = value):
            Set "var_%%~Q=%%~R"
        )
        SetLocal EnableDelayedExpansion
    )
@Echo SomeVariableName1=!var_SomeVariableName1!>>Datafile.txt
@Echo SomeVariableName3=!var_SomeVariableName3!>>Datafile.txt
)