如何在纯批处理中解析JSon

如何在纯批处理中解析JSon,json,parsing,batch-file,for-loop,token,Json,Parsing,Batch File,For Loop,Token,我试图理解批处理文件中的for循环如何使用/F“delims=”选项迭代所有项,但不使用标记。我试过各种方法,但都失败了。首先,我知道还有其他读取json文件的方法,但我只对学习如何在没有任何外部程序jscript jq等的情况下在纯批处理中执行感兴趣。json格式如下所示,但项目的数量和顺序往往会有所不同 {"SomeVariableName": "SomeString", "SomeVariableName": "SomeString", "SomeVariableName": "SomeS

我试图理解批处理文件中的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
  )
或者,我可以使用换行符而不是CRLF:

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=!队伍:~1,-1!“删除JSon文件通常附带的大括号。

鉴于输入字符串的键(
SomeVariableName
)和值(
SomeString
)部分不包含
*
,因此它们实际上都包含在引号内。
”,键部分(
SomeVariableName
)不包含
=
,值部分(
SomeString
)不等于序列
+空格,以下可能起作用:

@echo关闭
rem//逐行读取JSON文件:
对于/F“usebackq delims=“%%L in”(“file.json”)do(
rem//存储当前行字符串:
设置“行=%%L”
setlocal EnableDelayedExpansion
rem//Replace key/value SECTOR`':“`by`:”`(删除空格):
设置“行=!行::”=“:”!”
rem//修剪开括号和闭括号“{`/`}”:
如果定义了行,则“!LINE:~,1!”=”{“set”LINE=!LINE:~1!”
如果定义了行如果“!LINE:~-1!”==“}”设置“LINE=!LINE:~,-1!”
rem//遍历键/值对(用“,”分隔):
对于(!行!)中的%%P,请执行以下操作(
端部
rem//分割键/值对:
对于/F“tokens=1*delims=:eol=:”%%Q in(“%%P”)do(
rem//删除引号,分配变量(键=值):
设置“%%~Q=%%~R”
)
setlocal EnableDelayedExpansion
)
端部
)
这种方法通过删除分隔冒号后面的空格来更改每个键/值对
“SomeVariableName”:“SomeString”
;由于
不是标准的令牌分隔符,与空格和逗号相对,因此标准可以作为单个项迭代每个键/值对;然后可以使用a在
处拆分键和值;最后,每个零件的周围引号
将被删除,并完成赋值


进行切换是为了避免感叹号出现问题
出现在输入字符串中。

其中正在下载的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"}
下面的代码根据aschipfl的答案中修改的代码工作,即使SomeString包含空格

:: 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
)

另一种更简单的方法:

@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"}
{“SomeVariableName1”:“someString 1”、“SomeVariableName2”:“someString&StringString | 3”、“SomeVariableName4”:“someString 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"
SET“SomeVariableName1=someString 1”
设置“SomeVariableName2=Some&StringString | 3”
设置“SomeVariableName4=someString 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”

实际上,SomeString可能是一个包含各种字符的标题,因此唯一近似已知的值是SomeVariableName键,它们往往没有空格。我已经更新了我的问题,很抱歉忘记添加它。
SomeVariableName
SomeString
都可能包含空格;最近的编辑甚至允许序列冒号后跟空格…不需要用空格替换
+空格,因为空格、制表符、
,以及
=
,是等效的令牌分隔符。。。问题中应该已经提到了牙套……是的,我花了这么多时间想弄清楚,然后才把问题贴出来,当时我太累了,所以我就这样贴了出来,因为这不是我真正关心的问题。我不知道为什么你发布的代码不能按原样工作,但在替换为选项卡后它确实工作了。我是批处理新手,所以我会让其他人来找出原因,然后离开这篇文章,以防有人能从中受益。如果您想使用我正在处理的json文件类型对其进行测试,可以使用--dump json从youtube dl cli获取它。非常感谢你的帮助,很好!虽然没有