Ecco una soluzione ibrida Batch + PowerShell. PowerShell oggettifica (deserializza) il testo JSON e lo invia in formato chiave = valore per essere catturato e impostato come variabili batch dal ciclo del lotto. Salvalo con un'estensione .bat e provalo.
<# : batch portion (contained within a PowerShell multi-line comment)
@echo off & setlocal
set "JSON={ "year": 2016, "time": "05:01" }"
rem # re-eval self with PowerShell and capture results
for /f "delims=" %%I in ('powershell "iex (${%~f0} | out-string)"') do set "%%~I"
rem # output captured results
set JSON[
rem # end main runtime
goto :EOF
: end batch/begin PowerShell hybrid code #>
add-type -AssemblyName System.Web.Extensions
$JSON = new-object Web.Script.Serialization.JavaScriptSerializer
$obj = $JSON.DeserializeObject($env:JSON)
# output object in key=value format to be captured by Batch "for /f" loop
foreach ($key in $obj.keys) { "JSON[{0}]={1}" -f $key, $obj[$key] }
Poi, se si desidera che solo l'anno e ora i valori, basta usare %JSON[year]%
o %JSON[time]%
.
Se stai leggendo il vostro JSON da un file .json, si potrebbe avere la parte PowerShell leggere il file, sostituendo ($env:JSON)
con ((gc jsonfile.json))
. Quindi non sarai affatto dipendente dal fatto che il tuo JSON sia multilinea e abbellito o minorato. Comunque sarà deserializzato allo stesso modo.
Se la velocità di esecuzione è un problema, è preferibile una soluzione ibrida Batch + JScript. Deserializza il JSON in un oggetto uguale alla soluzione PowerShell, ma richiamare JScript da un contesto Batch è più veloce che richiamare un comando o uno script di PowerShell da Batch.
@if (@CodeSection == @Batch) @then
@echo off & setlocal
set "JSON={ "year": 2016, "time": "05:01" }"
rem // re-eval self with JScript interpreter and capture results
for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0"') do set "%%~I"
rem // output captured results
set JSON[
rem // end main runtime
goto :EOF
@end // end Batch/begin JScript hybrid code
var htmlfile = WSH.CreateObject('htmlfile'),
txt = WSH.CreateObject('Wscript.Shell').Environment('process').Item('JSON');
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
var obj = htmlfile.parentWindow.JSON.parse(txt);
htmlfile.close();
for (var i in obj) WSH.Echo('JSON[' + i + ']=' + obj[i]);
E, come è il caso con la prima soluzione ibrida PowerShell, è possibile analizzare più righe JSON leggendo il file .json dall'interno della porzione JScript se lo si desidera (creando un oggetto Scripting.FileSystemObject
e chiamando i suoi metodi .OpenTextFile()
e .ReadAll()
).
Ecco un'altra soluzione lotto puro, ma che definisce coppie chiave = valore come array associativo evitare botte con %time%
come soluzione Aacini fa.Penso davvero che sia meglio analizzare JSON come un oggetto in un linguaggio di supporto piuttosto che come testo piatto in puro batch, ma mi rendo anche conto che la risposta migliore non è sempre la più popolare.
@echo off
setlocal
set "JSON={ "other": 1234, "year": 2016, "value": "str", "time": "05:01" }"
set "JSON=%JSON:~1,-1%"
set "JSON=%JSON:":=",%"
set mod=0
for %%I in (%JSON%) do (
set /a mod = !mod
setlocal enabledelayedexpansion
if !mod! equ 0 (
for %%# in ("!var!") do endlocal & set "JSON[%%~#]=%%~I"
) else (
endlocal & set "var=%%~I"
)
)
set JSON[
Per curiosità morbosa, perché lotto? JScript o PowerShell sarebbero più semplici per questo: entrambi hanno il supporto nativo per JSON. –
Ok, come apparirebbe in PowerShell? dato il file JSON, restituire i valori per anno e ora in uno script batch. – Andrei
@MarkReed: Mi piacerebbe vedere una soluzione PowerShell così "più semplice" (anche se molto più lenta) ... – Aacini