Batch file 批量解析简单的JSON字符串

Batch file 批量解析简单的JSON字符串,batch-file,Batch File,如何批量解析简单的JSON字符串 例如,如果我有以下JSON字符串: { "...":"...", “年份”:2016年, “时间”:“05:01”, "...":"...", } 这个JSON字符串有许多元素,其中两个是“年”和“时间”。从这个字符串中,我想在不使用任何外部库的情况下提取两个变量中“年”和“时间”的值(即,我不想为此安装或下载任何外部UTIL,新安装的Windows应该有所有必要的工具)。有不同的方法,这里有一种 @echo off set string={ "year": 2

如何批量解析简单的JSON字符串

例如,如果我有以下JSON字符串:

{ "...":"...", “年份”:2016年, “时间”:“05:01”, "...":"...", }


这个JSON字符串有许多元素,其中两个是“年”和“时间”。从这个字符串中,我想在不使用任何外部库的情况下提取两个变量中“年”和“时间”的值(即,我不想为此安装或下载任何外部UTIL,新安装的Windows应该有所有必要的工具)。

有不同的方法,这里有一种

@echo off
set string={ "year": 2016, "time": "05:01" }
set string=%string:"=%

for /f "tokens=3,5" %%a in ('echo %string%') do set d=%%a&set t=%%b
echo -%d%- -%t%-
pause & goto :EOF
还有第二点:

@echo off
set string={ "year": 2016, "time": "05:01" }

for /f "tokens=3,5" %%a in ('echo %string%') do set d=%%~a&set t=%%~b
echo -%d%- -%t%-
pause & goto :EOF
输出:

other="1234"
year="2016"
value="str"
time="05:01"
这种方法的一个小缺点是“time”批处理动态变量将被新的JSON变量替换,但是如果使用
setlocal
命令,这一点不会导致任何问题

编辑:只需完成cz3ch将结果放入“字符串”数组的请求,而不是将其放入单个变量中:

@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 array assignments
set "string[%string:, =" & set "string[%"

set string[

这是一个混合批处理+PowerShell解决方案。PowerShell将JSON文本对象化(反序列化)并以key=value格式输出,以供batch
for/f
循环捕获并设置为批处理变量。使用.bat扩展名保存此文件,并尝试一下


添加类型-AssemblyName System.Web.Extensions
$JSON=新对象Web.Script.Serialization.JavaScriptSerializer
$obj=$JSON.DeserializeObject($env:JSON)
#批处理“for/f”循环捕获的key=value格式的输出对象
foreach($obj.keys中的key){“JSON[{0}]={1}”-f$key,$obj[$key]}
如果只需要年份和时间值,只需使用
%JSON[year]
%JSON[time]]

如果您正在从.JSON文件读取JSON,则可以让PowerShell部分读取该文件,将
($env:JSON)
替换为
((gc jsonfile.JSON))
。这样,您就不会依赖于JSON是多行的、美化的还是缩小的。无论如何,它都将被反序列化


如果需要考虑执行速度,您可能更喜欢Batch+JScript混合解决方案。它将JSON反序列化为与PowerShell解决方案相同的对象,但从批处理上下文调用JScript要比从批处理上下文调用PowerShell命令或脚本快

@如果(@code节==@Batch)@那么
@echo off和setlocal
设置“JSON={“年”:2016,“时间”:“05:01”}”
rem//使用JScript解释器重新评估self并捕获结果
对于/f“delims=“%%I in('cscript/nologo/e:JScript”%~f0'),请设置“%%~I”
rem//输出捕获的结果
设置JSON[
rem//结束主运行时
后藤:EOF
@结束//结束批处理/开始JScript混合代码
var htmlfile=WSH.CreateObject('htmlfile'),
txt=WSH.CreateObject('Wscript.Shell').Environment('process').Item('JSON');
htmlfile.write(“”);
var obj=htmlfile.parentWindow.JSON.parse(txt);
htmlfile.close();
对于(obj中的var i)WSH.Echo('JSON['+i+']='+obj[i]);
与第一个PowerShell混合解决方案一样,如果愿意,您可以通过从JScript部分中读取.JSON文件来解析多行JSON(通过创建
脚本.FileSystemObject
对象并调用其
.OpenTextFile()
ReadAll()
方法)


这里有另一个纯批处理解决方案,但它将key=value对设置为关联数组,以避免像Aacini的解决方案那样踩在
%time%
上。我真的认为最好将JSON解析为助手语言中的对象,而不是纯批处理中的纯文本,但我也意识到最好的答案并不总是最流行的拉尔

@echo关闭
setlocal
设置“JSON={“其他”:1234,“年份”:2016,“值”:“str”,“时间”:“05:01”}”
设置“JSON=%JSON:~1,-1%”
设置“JSON=%JSON::=”,%
设置mod=0
对于(%JSON%)中的%%I,请执行以下操作(
set/a mod=!mod
延迟扩展
如果!mod!eq 0(
对于(“!var!”)中的%%#,请执行endlocal并设置“JSON[%~+]=%%I”
)否则(
endlocal&设置“var=%%~I”
)
)
设置JSON[
使用,无需批量使用powershell或字符串操作

从json字符串获取字段值的示例:

set "year={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" } | jq .year"

echo %year%
为您提供2016年

,包括:


出于病态的好奇,为什么要批处理?JScript或PowerShell对此更简单-它们都有JSON的本机支持。好的,这在PowerShell中会是什么样子?给定JSON文件,在批处理脚本中返回年份和时间的值。@MarkReed:我希望看到这样的“更简单”(尽管速度慢得多)PowerShell解决方案…您可能会丢失这些吓人的引号,@Aacini。与专门为解析JSON格式而设计的现有、经过测试的库相比,动态使用定制字符串操作解析JSON(或任何其他结构化格式)几乎总是一个错误的解决方案。如果您使用这些语言中的任何一种编写,execution速度不是您的首要任务。请参阅。从JSON字符串中获取有用的PowerShell对象是一行代码:
$string | ConvertFrom JSON
。我认为这“更简单”@MarkReed我非常同意将JSON反序列化为对象要比将JSON作为纯文本删除要好得多。不幸的是,
ConvertFrom JSON
仅在PowerShell 3.0+中可用。大多数Win 7 Box(我使用过的任何一个)默认为PowerShell 2.0,这使得使用该cmdlet部署脚本对于许多最终用户来说是个问题。但是,创建
System.Web.script.Serialization.JavaScriptSerializer
对象只需要一个参数。这是硬编码的,例如,如果我的json中有其他元素,并且我只想检索年份和时间,我如何知道它们Rindeces@Andrei最好的方法是问你想要答案的问题。这是一个很有哲理的评论,但我现在更新了我的问题。简单的回答很好!很好的解决方案!我们如何将它们放在数组中而不是放在单个变量中?例如string[time]使用了这个解决方案,但更新了一点b
set "year={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" } | jq .year"

echo %year%
for /f "tokens=* delims=" %%a in ('jsonextractor.bat simple.json year') do set "year=%%~a"

for /f "tokens=* delims=" %%a in ('jsonextractor.bat simple.json time') do set "time_=%%~a"

echo %year% -- %time_%