Несколько ForEach с массивами в Powershell - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь сгенерировать два файла данных (первый для каждого) и создать только один документ для каждого файла (второй для каждого). Я могу сгенерировать два файла данных просто отлично, однако он создает 2 документа и назначает их каждому файлу. Мне просто нужно назначить один документ одному файлу, а затем другой документ другому файлу. Я боролся и не смог найти решение (начинающий разработчик). Что я могу сделать для этого?

$filepath="C:\files\pdf\"
$data_files = Get-ChildItem $filepath
$filesss=$data_files | Write-Output

$Data2= $filesss -split "`n"
$i2=0
$var=@()

$gravy= Get-Content "C:\files\temp.txt"
$ia=0
$data44=@()


foreach  ($item2 in $Data2)
         {

          $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
          $headers.Add("Accept", 'application/pdf')

          $fileName="C:\files\pdf\$item2"
          $fileContent = get-content -Raw $fileName
          $fileContentBytes = [System.Text.Encoding]::Default.GetBytes($fileContent)
          $fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)



foreach($id in $gravy){

                        $data44= ConvertTo-Json @{
                             encrypted="false";
                             allowSaveBinaryData="true";
                             binaryData="$fileContentEncoded"
                             divider="Expense Report";
                             extension="pdf";
                             name="$fileContentEncoded";
                             relProjectId="31";
                            }

           $var2[$i2]="https://XXXXXXX.com/v4/documents/$id/?guid=$AUTHtemp&fbsite=https://API/"

           Invoke-RestMethod -headers $headers -ContentType 'application/json' -Method PUT -body $data44 -Uri $var2 

           $ia++
                       }
$i2++ }

1 Ответ

0 голосов
/ 26 апреля 2018

Хорошо, я переместил некоторые вещи за пределы вашего цикла, полностью удалил один цикл и изменил его на цикл For. Вот что происходит, и почему я это изменил.

Оригинал (упрощенно):

ForEach($file in $files){
    <load file>
    ForEach($id in temp.txt){
        <Generate a document>
    }
}

Итак, предположим, у вас есть FileA.pdf и FileB.pdf для обработки, а temp.txt имеет 2 строки 'ID1' и 'ID2'. Фактическое содержание не имеет значения, количество строк имеет большее значение.

Итак, внешний цикл запускается и загружает данные для FileA.pdf.
Затем запускается внутренний цикл, получает данные для FileA.pdf и использует «ID1» для создания файла.
Закончив с первым элементом в файле temp.txt, он переходит к следующему (это цикл, это то, что делают циклы). Он берет данные для FileA.pdf и использует «ID2» для создания файла.
Внутренний цикл завершил все в файле temp.txt, поэтому мы вернемся к внешнему циклу.
Внешний цикл теперь загружает данные для FileB.pdf.
Затем внутренний цикл запускается снова, берет данные для FileB.pdf и использует «ID1» для создания файла.
Внутренний цикл перемещается к следующему элементу в файле temp.txt, использует данные из файла FileB.pdf и использует «ID2» для создания другого файла.
Внутренний цикл завершен, возвращен к внешнему циклу, он тоже выполнен, сценарий завершен.

Проблема в том, что внутренний цикл обрабатывает все в файле temp.txt для каждой итерации внешнего цикла, поэтому 2 файла pdf x 2 идентификатора в файле temp.txt = всего 4 файла.

Теперь, используя цикл For, мы используем число, основываем его на количестве элементов в файле temp.txt и используем это число для перебора списка документов и идентификаторов. Вот что я написал:

#Define the path to PDF files
$filepath="C:\files\pdf"
#Get list of PDF files
$data_files = Get-ChildItem $filepath
#Import the gravy! MMmm... gravy
$gravy= Get-Content "C:\files\temp.txt"

#Setup variables that won't change per file
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Accept", 'application/pdf')
$data44=@{}

#Loop through items in the gravy file, and load 1 pdf per item
for ($i = 0; $i -lt $gravy.count; $i++)
{
    #Get raw string data from PDF file
    $fileContent = get-content -Raw $data_files[$i].FullName
    #Convert the raw data to bytes
    $fileContentBytes = [System.Text.Encoding]::Default.GetBytes($fileContent)
    #Encode the bytes as a Base64String for uploading
    $fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)

    #Get the id to use for this file
    $id = $gravy[$i]

    #Prep body to POST ...seriously though, you set the name to be the Base64 encoded string? Do you use binary in casual conversation as well?
    $data44= ConvertTo-Json @{
        encrypted="false";
        allowSaveBinaryData="true";
        binaryData="$fileContentEncoded"
        divider="Expense Report";
        extension="pdf";
        name="$fileContentEncoded";
        relProjectId="31";
    }

    #Define the URI to POST to
    $var2="https://XXXXXXX.com/v4/documents/$id/?guid=$AUTHtemp&fbsite=https://API/"

    #Post the data to the REST API
    Invoke-RestMethod -headers $headers -ContentType 'application/json' -Method PUT -body $data44 -Uri $var2 

}

Я добавил несколько комментариев, чтобы попытаться разобраться в этом. Дайте мне знать, если это работает для вас, или у вас есть какие-то конкретные вопросы о том, как это работает.

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