我创建了一个批处理文件,该文件读取包含npm包及其版本的.json
文件。
现在一切正常,除了在写入文件
之前连接2个变量中的值这是InstallPackage.json
文件:
{
"dependencies": {
"@types/react": "16.3.10",
"react": "16.3.2",
"react-dom": "16.3.2",
"react-scripts": "1.1.4"
},
"devdependencies":{}
}
这是批处理文件:
<# : batch portion (contained within a PowerShell multi-line comment)
@echo off & setlocal
setlocal EnableDelayedExpansion
set LF=^
set JSON=
for /f "delims=" %%x in (InstallPackage.json) do (
set "JSON=!JSON!%%x!LF!"
)
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) {
foreach($package in $obj[$key].keys){
### error happens here ###
echo $package@$obj[$key][$package] >> packages.txt
}
}
而不是
@types/react@16.3.10
我明白了:
@types/react@System.Collections.Generic.Dictionary`2[System.String,System.Object][dependencies][@types/react]
这是一个简单的连接,不知道它为什么不起作用。
答案 0 :(得分:1)
您的PowerShell输出行不是PowerShell-ese。它有点像PowerCmd。取代
echo $package@$obj[$key][$package] >> packages.txt
与
"JSON[{0:d}]={1}@{2}" -f $i++, $package, $obj[$key][$package] >> packages.txt
...如果要在PowerShell退出批处理环境时填充JSON []数组,或者
"{0}@{1}" -f $package, $obj[$key][$package] >> packages.txt
...如果您只想将连接的值发送到packages.txt。如果是这种情况,请在批处理中删除for /F
循环。您还可以在PowerShell中使用gc
来读取JSON,这比尝试使用多行值填充Batch变量要优雅得多。
<# : batch portion (contained within a PowerShell multi-line comment)
@echo off & setlocal
set "JSON=InstallPackage.json"
rem # re-eval self with PowerShell and capture results
powershell -noprofile "iex (${%~f0} | out-string)"
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((gc $env:JSON))
# output object in key@value format to packages.txt
foreach ($key in $obj.keys) {
foreach($package in $obj[$key].keys){
"{0}@{1}" -f $package, $obj[$key][$package] >> packages.txt
}
}
我还有一个推荐。如果使用out-file
cmdlet,您的意图将更清晰,而不是使用追加重定向编写packages.txt。您是否希望在每次运行时从头开始创建packages.txt?或者,packages.txt会在多次运行中继续增长吗?如果你从现在起一年后重新访问这段代码,你会记得你的意图吗?
这会更清楚:
# output object in key@value format to packages.txt
&{
foreach ($key in $obj.keys) {
foreach($package in $obj[$key].keys){
"{0}@{1}" -f $package, $obj[$key][$package]
}
}
} | out-file packages.txt
如果您打算通过连续运行来增加packages.txt,请使用
out-file packages.txt -append
请参阅?这样,packages.txt将在每次运行时显式覆盖或附加,并且不需要检查文件是否已存在或期望文件不存在。这种方式不那么模糊。
答案 1 :(得分:0)
这么简单的东西需要很多代码。至少对于Xidel:
xidel -s InstallPackage.json -e "let $a:=$json/dependencies return $a() ! join((.,$a(.)),'@')" >> packages.txt
' package.txt ':
@types/react@16.3.10
react@16.3.2
react-dom@16.3.2
react-scripts@1.1.4