Đây là giải pháp Batch + PowerShell lai. PowerShell phản đối (deserializes) văn bản JSON và xuất nó trong định dạng khóa = giá trị được bắt và được đặt làm các biến lô theo vòng lặp lô for /f
. Lưu này với một phần mở rộng .bat và cho nó một shot.
<# : 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] }
Sau đó, nếu bạn muốn chỉ có giá trị trong năm và thời gian, chỉ cần sử dụng %JSON[year]%
hoặc %JSON[time]%
.
Nếu bạn đang đọc JSON của mình từ tệp .json, bạn có thể có phần PowerShell đọc tệp, thay thế ($env:JSON)
bằng ((gc jsonfile.json))
. Sau đó, bạn sẽ không phụ thuộc chút nào vào việc liệu JSON của bạn có đa dòng và được làm đẹp hay được rút gọn hay không. Nó sẽ được deserialized tất cả cùng một trong hai cách.
Nếu tốc độ thực thi là mối quan tâm, bạn có thể thích giải pháp lai Batch + JScript. Nó deserializes JSON vào một đối tượng giống như các giải pháp PowerShell, nhưng gọi JScript từ một bối cảnh Batch là nhanh hơn so với gọi một lệnh PowerShell hoặc kịch bản từ hàng loạt.
@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]);
Và như là trường hợp với các giải pháp PowerShell hybrid đầu tiên, bạn có thể phân tích nhiều dòng JSON bằng cách đọc các tập tin .json từ bên trong phần JScript nếu bạn muốn (bằng cách tạo ra một đối tượng Scripting.FileSystemObject
và gọi các phương thức .OpenTextFile()
và .ReadAll()
).
Đây là một giải pháp hàng loạt tinh khiết, nhưng một trong đó đặt cặp giá trị key = như một mảng kết hợp để tránh dẫm chân lên %time%
như giải pháp Aacini của không.Tôi thực sự nghĩ tốt hơn là phân tích cú pháp JSON như một đối tượng trong ngôn ngữ trợ giúp chứ không phải là văn bản thuần trong lô thuần túy, nhưng tôi cũng nhận ra rằng câu trả lời hay nhất không phải lúc nào cũng phổ biến nhất.
@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[
Vì tò mò, tại sao lại là hàng loạt? JScript hoặc PowerShell sẽ đơn giản hơn cho điều này - cả hai đều có hỗ trợ riêng cho JSON. –
Ok, tính năng này sẽ trông như thế nào trong PowerShell? cho tệp JSON, trả lại giá trị cho năm và thời gian trong tập lệnh theo lô. – Andrei
@MarkReed: Tôi muốn thấy giải pháp PowerShell "đơn giản hơn" (mặc dù chậm hơn nhiều) ... – Aacini