json - 如何在纯批处理中解析 JSON
问题描述
我试图了解批处理文件中的 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 文件一起提供的花括号。
解决方案
另一种更简单的方法:
@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"
推荐阅读
- ios - 帧时间戳要么乱序要么重复
- kendo-ui - KendoUI 图表 - 修复饼图宽度而不是 chartArea 以避免切割部分图例
- powershell - 如何使用powershell处理无限循环的日志文件?
- git - yarn publish 失败,因为 dist 文件夹被添加到 gitignore
- html - 我可以将 .col 放在另一个 col 中吗?
- sql - 选择仅工作日的数据并计算差异
- javascript - 如何增加 http 请求的默认超时时间?
- java - 为什么我得到的 IWorkspaceRoot 为空?
- postgresql - 查询以查找 3 个时间戳(ts),其中第一个最接近给定 ts,2 个最接近找到的第一个
- selenium-webdriver - 通过使用 selenium webdriver 验证同一表的两个不同列的值,单击 webtable 特定单元格的按钮