在 powershell 中计数并循环直到 csv 结束

count and loop in powershell until the end of a csv

我是代码新手,很抱歉,如果问题看起来很假

所以我循环 csv 数据来构建一个 xml

我的问题是我最多只能在 xml 中放置 5000 个文件,而我需要放置超过 100 万个文件? 所以我将制作多个 xml,每个文件有 5000 个文件 我的代码的第一部分已经完成。 现在我需要创建一个计数器,它会在我的第一个“for each”循环中说 一旦我达到 5000 行(等 5000 文件)我需要 return 到我第一次治疗的开始 我找不到生成倍数 xml

的方法

do/while do/until及其制作方法

这是我的 csv 示例

    UCB63_DATENUM;U6618_FILENAME;UF6E8_CANAL;U65B8_IDRP
    7/8/19 22:27;457E6659_ZN_LIQRLVPR_A_V_ML.pdf;ML;1367091
    9/11/19 23:03;49453878_ZN_LIQRLVPR_A_V_ML.pdf;ML;106440
    9/24/19 21:04;497E585B_ZN_LIQRLVPR_A_V_CS.pdf;CS;1536658
    2/12/20 22:12;58453B75_ZN_LIQRLVPR_A_V_ML.pdf;ML;1406091

所以我想我可以数出第一列的行数 达到 5000 我调用我的第一个循环

如果您需要更多信息,请直接询问,我不知道该怎么做

好的,我会把整个代码给你

    $FREQUENCE_DECOMPTE = 'Index Nom="FREQUENCE_DECOMPTE" Valeur="MENS"'
    
    $LIBELLE_ORGANISME = 'Index Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"'
    
    $MONTANT_TOTAL = 'Index Nom="MONTANT_TOTAL" Valeur="0"'
    
    $POLE = 'Index Nom="POLE" Valeur="1ADP"'
    
    $CODE_ORGANISME = 'Index Nom="CODE_ORGANISME" Valeur="1ADP"'
    
    $RecupDateFinTraitement = Get-Date
    
    ndDate = $recupdatefintraitement.AddDays(30)
    
    $liste = Import-Csv -path C:\Temp\test.csv -Delimiter ';'
     
    Import-Csv -path C:\Temp\test.csv -Delimiter ';'
    
    $boucle = foreach ($list in $liste)
    
    {
    
        $list.U6618_FILENAME
    
        $FREQUENCE_DECOMPTE
    
        $LIBELLE_ORGANISME
    
        $MONTANT_TOTAL
    
        $list.UCB63_DATENUM
    
        $POLE
    
        $CODE_ORGANISME
    
        $list.U6618_FILENAME
    
        $list.U65B8_IDRP
    
        $RecupDateFinTraitement.ToString('dd/MM/yyyy')
    
        ndDate.ToString('dd/MM/yyyy')
    
        $ALERTEMAIL.UF6E8_CANAL
     
        $fin = $list.UF6E8_CANAL -match "ML"
    
        if ($list.UF6E8_CANAL -match "ML"){1}
    
        else {0}
    
        **## Compteur
    
        $Compte = Get-Content C:\Temp\test.csv | Measure-Object -Line
        $compte.lines
        if ($Compte.Lines -gt 2)
        {
             do{$boucle} until ($Compte -gt 5) 
        }**
     
    
    }
    
    $boucle | Out-File -FilePath C:\Temp\test2.txt

我不认为 xml 的解释会有帮助我只是想在第一个循环中闲逛,以便在第一个输出文件中达到 5000 个文档时重新启动名为 $boucle 的第一个循环(或一旦我到达 csv 的第 5000 行,可能会更容易) 正如您通过输出文件的名称看到的 xml 我仍然在研究

的形状

此致

听起来您想做两件事:

  • 将一个包含 1,000,000 多条记录的数组从一个 csv 文件分成 5000 个批次
  • 为每批 5000 条记录创建一个 xml 文档

我们可以用这样的辅助函数做第一步:

function ConvertTo-Batches
{
    param(
        [Parameter(ValueFromPipeline=$true)]
        $InputArray,
        $Size
    )
    BEGIN {
        $batch = @();
        $counter = 1;
    }
    PROCESS {
        $batch += $_;
        if( $batch.Length -eq $Size )
        {
            write-output @(, $batch);
            $batch = @();
            $counter += 1;
        }
    }
    END {
        if( $batch.Length -gt 0 )
        {
            write-output @(, $batch);
        }
    }
}

你可以这样使用:

@( 1, 2, 3, 4, 5 ) | ConvertTo-Batches -Size 2 | ForEach-Object { write-host $_ }
# batches = 
# 1 2
# 3 4
# 5

然后您需要做的就是将每个批次传递给第二个函数,该函数输出该批次的 xml 文档:

function Convert-BatchToXmlDocument
{
    param(
        [Parameter(ValueFromPipeline=$true)]
        $Batch
    )
    BEGIN {
        $counter = 1;
    }
    PROCESS {
        $filename = "myfile-$counter.xml";
        # ... convert a batch to xml here ...
        $counter += 1;
    }
}

放在一起,你的代码变成这样:

$csv = @"
UCB63_DATENUM;U6618_FILENAME;UF6E8_CANAL;U65B8_IDRP
7/8/19 22:27;457E6659_ZN_LIQRLVPR_A_V_ML.pdf;ML;1367091
9/11/19 23:03;49453878_ZN_LIQRLVPR_A_V_ML.pdf;ML;106440
9/24/19 21:04;497E585B_ZN_LIQRLVPR_A_V_CS.pdf;CS;1536658
2/12/20 22:12;58453B75_ZN_LIQRLVPR_A_V_ML.pdf;ML;1406091
"@

$csv | ConvertFrom-Csv -Delimiter ";" | ConvertTo-Batches -Size 3 | Convert-BatchToXmlDocument

当然不确定你想如何格式化你的XML,但下面的代码应该给你一个方法来做到这一点。

$FREQUENCE_DECOMPTE     = 'Nom="FREQUENCE_DECOMPTE" Valeur="MENS"'
$LIBELLE_ORGANISME      = 'Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"'
$MONTANT_TOTAL          = 'Nom="MONTANT_TOTAL" Valeur="0"'
$POLE                   = 'Nom="POLE" Valeur="1ADP"'
$CODE_ORGANISME         = 'Nom="CODE_ORGANISME" Valeur="1ADP"'

# read the csv file
$liste = Import-Csv -path 'D:\Test\test.csv' -Delimiter ';'

# get the total remaining records to process
$remaining = $liste.Count

# set a maximum value of items for each resulting XML file
$maxItemsPerXml = 3

# set a xml output file counter and an item index counter
$xmlFileCount = 1
$currentItem  = 0
# loop through all items
while ($remaining -gt 0) {
    $itemCount = [math]::Min($maxItemsPerXml, $remaining)
    $xmlItems = for ($i = 0; $i -lt $itemCount; $i++) {
        $item = $liste[$i + $currentItem]
        $fin  = if ($item.UF6E8_CANAL -eq "ML") {1} else {0}
        # parse the date from the 'UCB63_DATENUM' field
        $date = [datetime]::ParseExact($item.UCB63_DATENUM, 'M/d/yy HH:mm', $null)
        $RecupDateFinTraitement = $date.ToString('dd/MM/yyyy')
        $RecupDateFin30         = $date.AddDays(30).ToString('dd/MM/yyyy')

        # output each item in xml-style
        # you can change the element names to whatever you want of course
@"
    <Item>
        <U6618_FILENAME>$($item.U6618_FILENAME)</U6618_FILENAME>
        <Indices>
            <Index $FREQUENCE_DECOMPTE></Index>
            <Index $LIBELLE_ORGANISME></Index>
            <Index $MONTANT_TOTAL></Index>
            <Index $POLE></Index>
            <Index $CODE_ORGANISME></Index>
        </Indices>
        <UCB63_DATENUM>$($item.UCB63_DATENUM)</UCB63_DATENUM>
        <U65B8_IDRP>$($item.U65B8_IDRP)</U65B8_IDRP>
        <RecupDateFinTraitement>$RecupDateFinTraitement</RecupDateFinTraitement>
        <RecupDateFin30>$RecupDateFin30</RecupDateFin30>
        <ALERTEMAIL>$($item.UF6E8_CANAL)</ALERTEMAIL>
        <Fin>$fin</Fin>
    </Item>
"@  

    }

    # create a complete file path and name for the output xml
    $xmlFile = 'D:\Test\Test_{0:D8}.xml' -f $xmlFileCount
    # create the XML content, complete with declaration and root node and write it to file
@"
<?xml version="1.0" encoding="utf-8"?>
<root>
$($xmlItems -join "`r`n")
</root>
"@ | Set-Content -Path $xmlFile -Encoding UTF8

    # update the counters
    $xmlFileCount++
    $remaining -= $itemCount
    $currentItem += $itemCount
}

您可能想要修改 XML 现在使用 Here-String 模板构建的方式。我只是将 CSV 中的 header 名称作为元素名称,除了您在所有大写中定义的 indices 变量。

从那些我取下 Index 部分并将其设置为元素名称。

使用您的示例 CSV 和 $maxItemsPerXml = 3 的输出将是 2 个名为 Test_00000001.xmlTest_00000002.xml 的文件。

Test_00000001.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
    <Item>
        <U6618_FILENAME>457E6659_ZN_LIQRLVPR_A_V_ML.pdf</U6618_FILENAME>
        <Indices>
            <Index Nom="FREQUENCE_DECOMPTE" Valeur="MENS"></Index>
            <Index Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"></Index>
            <Index Nom="MONTANT_TOTAL" Valeur="0"></Index>
            <Index Nom="POLE" Valeur="1ADP"></Index>
            <Index Nom="CODE_ORGANISME" Valeur="1ADP"></Index>
        </Indices>
        <UCB63_DATENUM>7/8/19 22:27</UCB63_DATENUM>
        <U65B8_IDRP>1367091</U65B8_IDRP>
        <RecupDateFinTraitement>08-07-2019</RecupDateFinTraitement>
        <RecupDateFin30>07-08-2019</RecupDateFin30>
        <ALERTEMAIL>ML</ALERTEMAIL>
        <Fin>1</Fin>
    </Item>
    <Item>
        <U6618_FILENAME>49453878_ZN_LIQRLVPR_A_V_ML.pdf</U6618_FILENAME>
        <Indices>
            <Index Nom="FREQUENCE_DECOMPTE" Valeur="MENS"></Index>
            <Index Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"></Index>
            <Index Nom="MONTANT_TOTAL" Valeur="0"></Index>
            <Index Nom="POLE" Valeur="1ADP"></Index>
            <Index Nom="CODE_ORGANISME" Valeur="1ADP"></Index>
        </Indices>
        <UCB63_DATENUM>9/11/19 23:03</UCB63_DATENUM>
        <U65B8_IDRP>106440</U65B8_IDRP>
        <RecupDateFinTraitement>11-09-2019</RecupDateFinTraitement>
        <RecupDateFin30>11-10-2019</RecupDateFin30>
        <ALERTEMAIL>ML</ALERTEMAIL>
        <Fin>1</Fin>
    </Item>
    <Item>
        <U6618_FILENAME>497E585B_ZN_LIQRLVPR_A_V_CS.pdf</U6618_FILENAME>
        <Indices>
            <Index Nom="FREQUENCE_DECOMPTE" Valeur="MENS"></Index>
            <Index Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"></Index>
            <Index Nom="MONTANT_TOTAL" Valeur="0"></Index>
            <Index Nom="POLE" Valeur="1ADP"></Index>
            <Index Nom="CODE_ORGANISME" Valeur="1ADP"></Index>
        </Indices>
        <UCB63_DATENUM>9/24/19 21:04</UCB63_DATENUM>
        <U65B8_IDRP>1536658</U65B8_IDRP>
        <RecupDateFinTraitement>24-09-2019</RecupDateFinTraitement>
        <RecupDateFin30>24-10-2019</RecupDateFin30>
        <ALERTEMAIL>CS</ALERTEMAIL>
        <Fin>0</Fin>
    </Item>
</root>

Test_00000002.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
    <Item>
        <U6618_FILENAME>58453B75_ZN_LIQRLVPR_A_V_ML.pdf</U6618_FILENAME>
        <Indices>
            <Index Nom="FREQUENCE_DECOMPTE" Valeur="MENS"></Index>
            <Index Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"></Index>
            <Index Nom="MONTANT_TOTAL" Valeur="0"></Index>
            <Index Nom="POLE" Valeur="1ADP"></Index>
            <Index Nom="CODE_ORGANISME" Valeur="1ADP"></Index>
        </Indices>
        <UCB63_DATENUM>2/12/20 22:12</UCB63_DATENUM>
        <U65B8_IDRP>1406091</U65B8_IDRP>
        <RecupDateFinTraitement>12-02-2020</RecupDateFinTraitement>
        <RecupDateFin30>13-03-2020</RecupDateFin30>
        <ALERTEMAIL>ML</ALERTEMAIL>
        <Fin>1</Fin>
    </Item>
</root>