在写入文件之前美化 JSON 的 cURL 下载
beautify cURL download of JSON before writing to file
我正在使用 cURL 7.39.0 调用 REST 网络服务并将响应写入 .json
文件:
curl -L-X POST -b cookies.txt -H "Content-Type: application/json" http://localhost:7001/web/service/url -d {"param1":"value1"} -o "C:\output\serviceName.json"
响应被写入输出文件,但没有格式化:
{"status": "success","user": "name", "regId": "14420","subscriber": [{"memberFor":"3 years","lastLogin":"2 days ago"}]}
我的问题是:
有没有办法在将 JSON 响应写入输出文件之前对其进行格式化(如下所示)?
{
"status": "success",
"user": "name",
"regId": "14420",
"subscriber": [
{
"memberFor":"3 years",
"lastLogin":"2 days ago"
}
]
}
如果无法通过 cURL 进行格式化,我希望编写一个简单的批处理文件来自动打开 JSON 输出文件并应用格式化。类似于:
@echo off
cls
"C:\Program Files\Notepad++\notepad++" "C:\output\serviceName.json"
pause
batch/console 中是否有任何 flags/options 可用以实现此目的?
编辑: 我找到了一个使用 htmlfile
COM 对象的解决方案,它应该提供最快的性能(至少对于单个 运行)和不需要互联网连接。请参阅此答案中的最后一个解决方案。
因为你用 [batch-file] 标签标记了这个问题,并且因为我发现这个挑战很有趣,所以我写了一个混合批处理 + JScript 脚本来美化你的 JSON。由于 JScript 5.7 doesn't natively support the JSON object,此脚本使用外部 json2.js,如果尚未下载,则通过 XHR 下载它。从那里开始,调用 JavaScript 熟悉的 JSON.stringify()
方法及其美化选项是一件简单的事情。
语法:
json_generator | batfile.bat
-or-
batfile.bat < jsonfile.json
用法示例:
beautify.bat < "C:\output\serviceName.json" > "C:\output\beautified.json"
这导致以下内容被保存为 beautified.json:
{
"status": "success",
"user": "name",
"regId": "14420",
"subscriber": [
{
"memberFor": "3 years",
"lastLogin": "2 days ago"
}
]
}
代码:
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end Batch / begin JScript hybrid chimera
var xObj = WSH.CreateObject('Microsoft.XMLHTTP'),
fso = WSH.CreateObject('Scripting.FileSystemObject'),
temp = WSH.CreateObject('WScript.Shell').Environment('Process')('temp'),
j2lib = 'https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js',
json = WSH.StdIn.ReadAll();
if (fso.FileExists(temp + '\json2.js')) {
j2lib = fso.OpenTextFile(temp + '\json2.js', 1);
eval(j2lib.ReadAll());
j2lib.Close();
}
else {
with (xObj) {
open("GET", j2lib, true);
setRequestHeader('User-Agent', 'XMLHTTP/1.0');
send('');
}
while (xObj.readyState != 4) WSH.Sleep(50);
eval(xObj.responseText);
j2lib = fso.CreateTextFile(temp + '\json2.js', true);
j2lib.Write(xObj.responseText);
j2lib.Close();
}
WSH.Echo(JSON.stringify(JSON.parse(json), null, '\t'));
这是另一个不需要下载的使用相同语法的解决方案 json2.js。它通过不可见地启动 Internet Explorer,调用 IE 的内置 JSON 方法,然后再次静默关闭 IE 来避免这种情况。这很可能会比上面的方法慢,并且它可能会被阻止,具体取决于机器安全策略;但它确实具有无需 Internet 连接即可工作的优势。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end Batch / begin JScript hybrid chimera
var IE = WSH.CreateObject('InternetExplorer.Application'),
json = WSH.StdIn.ReadAll();
IE.Visible = 0;
IE.Navigate('about:blank');
while (IE.Busy || IE.ReadyState != 4) WSH.Sleep(25);
var JSON = IE.document.parentWindow.JSON,
pretty = JSON.stringify(JSON.parse(json), null, "\t");
WSH.Echo(pretty);
IE.Quit();
try { while (IE && IE.Busy) WSH.Sleep(25); }
catch(e) {}
这是另一种解决方案,这次使用批处理/HTA 混合。有一个 <meta>
标签强制 HTA 解释器兼容 IE9,因此包括
支持 JSON 方法。这比 IE 方法更快,但并非完全不可见。 HTA window 在屏幕上闪烁一瞬间,然后自行关闭。
<!-- : batch portion
@echo off & setlocal
rem // The for /f loop forces mshta to communicate with stdout
rem // as a console script host. Without for /f, attempting
rem // to write to stdout results in an invalid handle error.
for /f "delims=" %%I in ('mshta.exe "%~f0"') do echo(%%I
goto :EOF
end batch / begin HTA : -->
<meta http-equiv="x-ua-compatible" content="IE=9" />
<script>
var fso = new ActiveXObject('Scripting.FileSystemObject'),
stdin = fso.GetStandardStream(0),
stdout = fso.GetStandardStream(1),
json = stdin.ReadAll(),
pretty = JSON.stringify(JSON.parse(json), null, '\t');
close(stdout.Write(pretty));
</script>
我认为最好的解决方案是使用 scantily-documented htmlfile
COM 对象。使用与 <meta>
标记相同的技巧来强制它与 IE9 兼容,如上面的 HTA 解决方案所示,htmlfile
COM 对象提供对 JSON 方法的本机支持,而无需下载库,并且没有分叉额外的 windowed 帮助应用程序。它只是加载一个 dll。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end batch / begin JScript hybrid chimera
var htmlfile = WSH.CreateObject('htmlfile'),
json = WSH.StdIn.ReadAll();
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
var JSON = htmlfile.parentWindow.JSON,
pretty = JSON.stringify(JSON.parse(json), null, '\t');
htmlfile.close(WSH.Echo(pretty));
只是对老问题的更新。
https://stedolan.github.io/jq/ 是个不错的工具。默认情况下,jq 漂亮打印 JSON 输出。所以你可以做
curl ... | jq .
“。”是身份过滤器。参见 https://stedolan.github.io/jq/manual/#Invokingjq
我相信这一切都可以用 Xidel 来完成,默认情况下漂亮的打印:
xidel -s --method=POST ^
--load-cookies="cookies.txt" ^
-H "Content-Type: application/json" ^
-d {"param1":"value1"} ^
http://localhost:7001/web/service/url ^
-e "$json"
预期输出:
{
"status": "success",
"user": "name",
"regId": "14420"
"subscriber": [
{
"memberFor":"3 years",
"lastLogin":"2 days ago"
}
]
}
我正在使用 cURL 7.39.0 调用 REST 网络服务并将响应写入 .json
文件:
curl -L-X POST -b cookies.txt -H "Content-Type: application/json" http://localhost:7001/web/service/url -d {"param1":"value1"} -o "C:\output\serviceName.json"
响应被写入输出文件,但没有格式化:
{"status": "success","user": "name", "regId": "14420","subscriber": [{"memberFor":"3 years","lastLogin":"2 days ago"}]}
我的问题是:
有没有办法在将 JSON 响应写入输出文件之前对其进行格式化(如下所示)?
{ "status": "success", "user": "name", "regId": "14420", "subscriber": [ { "memberFor":"3 years", "lastLogin":"2 days ago" } ] }
如果无法通过 cURL 进行格式化,我希望编写一个简单的批处理文件来自动打开 JSON 输出文件并应用格式化。类似于:
@echo off cls "C:\Program Files\Notepad++\notepad++" "C:\output\serviceName.json" pause
batch/console 中是否有任何 flags/options 可用以实现此目的?
编辑: 我找到了一个使用 htmlfile
COM 对象的解决方案,它应该提供最快的性能(至少对于单个 运行)和不需要互联网连接。请参阅此答案中的最后一个解决方案。
因为你用 [batch-file] 标签标记了这个问题,并且因为我发现这个挑战很有趣,所以我写了一个混合批处理 + JScript 脚本来美化你的 JSON。由于 JScript 5.7 doesn't natively support the JSON object,此脚本使用外部 json2.js,如果尚未下载,则通过 XHR 下载它。从那里开始,调用 JavaScript 熟悉的 JSON.stringify()
方法及其美化选项是一件简单的事情。
语法:
json_generator | batfile.bat
-or-
batfile.bat < jsonfile.json
用法示例:
beautify.bat < "C:\output\serviceName.json" > "C:\output\beautified.json"
这导致以下内容被保存为 beautified.json:
{
"status": "success",
"user": "name",
"regId": "14420",
"subscriber": [
{
"memberFor": "3 years",
"lastLogin": "2 days ago"
}
]
}
代码:
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end Batch / begin JScript hybrid chimera
var xObj = WSH.CreateObject('Microsoft.XMLHTTP'),
fso = WSH.CreateObject('Scripting.FileSystemObject'),
temp = WSH.CreateObject('WScript.Shell').Environment('Process')('temp'),
j2lib = 'https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js',
json = WSH.StdIn.ReadAll();
if (fso.FileExists(temp + '\json2.js')) {
j2lib = fso.OpenTextFile(temp + '\json2.js', 1);
eval(j2lib.ReadAll());
j2lib.Close();
}
else {
with (xObj) {
open("GET", j2lib, true);
setRequestHeader('User-Agent', 'XMLHTTP/1.0');
send('');
}
while (xObj.readyState != 4) WSH.Sleep(50);
eval(xObj.responseText);
j2lib = fso.CreateTextFile(temp + '\json2.js', true);
j2lib.Write(xObj.responseText);
j2lib.Close();
}
WSH.Echo(JSON.stringify(JSON.parse(json), null, '\t'));
这是另一个不需要下载的使用相同语法的解决方案 json2.js。它通过不可见地启动 Internet Explorer,调用 IE 的内置 JSON 方法,然后再次静默关闭 IE 来避免这种情况。这很可能会比上面的方法慢,并且它可能会被阻止,具体取决于机器安全策略;但它确实具有无需 Internet 连接即可工作的优势。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end Batch / begin JScript hybrid chimera
var IE = WSH.CreateObject('InternetExplorer.Application'),
json = WSH.StdIn.ReadAll();
IE.Visible = 0;
IE.Navigate('about:blank');
while (IE.Busy || IE.ReadyState != 4) WSH.Sleep(25);
var JSON = IE.document.parentWindow.JSON,
pretty = JSON.stringify(JSON.parse(json), null, "\t");
WSH.Echo(pretty);
IE.Quit();
try { while (IE && IE.Busy) WSH.Sleep(25); }
catch(e) {}
这是另一种解决方案,这次使用批处理/HTA 混合。有一个 <meta>
标签强制 HTA 解释器兼容 IE9,因此包括
支持 JSON 方法。这比 IE 方法更快,但并非完全不可见。 HTA window 在屏幕上闪烁一瞬间,然后自行关闭。
<!-- : batch portion
@echo off & setlocal
rem // The for /f loop forces mshta to communicate with stdout
rem // as a console script host. Without for /f, attempting
rem // to write to stdout results in an invalid handle error.
for /f "delims=" %%I in ('mshta.exe "%~f0"') do echo(%%I
goto :EOF
end batch / begin HTA : -->
<meta http-equiv="x-ua-compatible" content="IE=9" />
<script>
var fso = new ActiveXObject('Scripting.FileSystemObject'),
stdin = fso.GetStandardStream(0),
stdout = fso.GetStandardStream(1),
json = stdin.ReadAll(),
pretty = JSON.stringify(JSON.parse(json), null, '\t');
close(stdout.Write(pretty));
</script>
我认为最好的解决方案是使用 scantily-documented htmlfile
COM 对象。使用与 <meta>
标记相同的技巧来强制它与 IE9 兼容,如上面的 HTA 解决方案所示,htmlfile
COM 对象提供对 JSON 方法的本机支持,而无需下载库,并且没有分叉额外的 windowed 帮助应用程序。它只是加载一个 dll。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
cscript /nologo /e:JScript "%~f0"
goto :EOF
@end // end batch / begin JScript hybrid chimera
var htmlfile = WSH.CreateObject('htmlfile'),
json = WSH.StdIn.ReadAll();
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
var JSON = htmlfile.parentWindow.JSON,
pretty = JSON.stringify(JSON.parse(json), null, '\t');
htmlfile.close(WSH.Echo(pretty));
只是对老问题的更新。 https://stedolan.github.io/jq/ 是个不错的工具。默认情况下,jq 漂亮打印 JSON 输出。所以你可以做
curl ... | jq .
“。”是身份过滤器。参见 https://stedolan.github.io/jq/manual/#Invokingjq
我相信这一切都可以用 Xidel 来完成,默认情况下漂亮的打印:
xidel -s --method=POST ^
--load-cookies="cookies.txt" ^
-H "Content-Type: application/json" ^
-d {"param1":"value1"} ^
http://localhost:7001/web/service/url ^
-e "$json"
预期输出:
{
"status": "success",
"user": "name",
"regId": "14420"
"subscriber": [
{
"memberFor":"3 years",
"lastLogin":"2 days ago"
}
]
}