Невозможно объединить значение 2 переменных в пакетном скрипте - PullRequest
0 голосов
/ 21 мая 2018

Я создал командный файл, который читает файл .json, содержащий пакеты npm и их версию.

Теперь все работает, кроме объединения значений в 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]

Это простая конкатенация, не знаю, почему она не работает.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Так много кода для чего-то такого простого.Как минимум для 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
0 голосов
/ 22 мая 2018

Ваша строка вывода PowerShell не совсем PowerShell-ese.Это что-то вроде PowerCmd или что-то в этом роде.Замените

echo $package@$obj[$key][$package] >> packages.txt

на

"JSON[{0:d}]={1}@{2}" -f $i++, $package, $obj[$key][$package] >> packages.txt

... если вы хотите заполнить массив JSON [] при выходе PowerShell обратно в среду пакетной обработки, или

"{0}@{1}" -f $package, $obj[$key][$package] >> packages.txt

... если вы хотите, чтобы только конкатенированные значения были отправлены в packages.txt.И если это так, избавьтесь от цикла for /F в пакетном режиме.Вы также можете использовать gc в PowerShell для чтения 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
    }
}

И у меня есть еще одна рекомендация,Вместо того, чтобы писать package.txt с помощью перенаправления добавления, ваши намерения будут более понятны, если вы используете командлет out-file.Ожидаете ли вы, что пакеты package.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

Если вы намереваетесь наращивать package.txt с последовательными запусками, тогдаиспользуйте

out-file packages.txt -append

Видите?Таким образом, package.txt будет явно либо перезаписываться, либо добавляться при каждом запуске, и не потребует никаких проверок, существует ли файл или ожидает, что файл еще не существует.Это менее двусмысленно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...