1

我有一个 200,000 个文件要使用 powershell 分成 8 个块

该文件具有第一个值为记录“KEY”的行

我想确保与键字段值(即行的第一个值)对应的行在拆分发生时不会跨文件中断。

这是我使用的简单拆分

$i=0
Get-Content -Encoding Default "C:\Test.csv" -ReadCount 10130 | ForEach-Object {
    $i++
    $_ | Out-File -Encoding Default "C:\Test_$i.csv"
}

样本数据
0190709,HP16,B,B,3,3,
0190709,HP17,B,B,3,3,
0190709,HP18,B,B,3,3,
0196597,HP11,,CNN,,,
0196597,HP119 ,,CNN,,,
0196597,HP13,,CNN,,,
01919769,HP11,,ANN,,,
01919769,HP119,,OPN,,,,
01919769,HP13,,CNN,,,
01919769,HP14,X,X, X,X,
01919769,HP15,A,A,X,X,
01919769,HP16,S,S,X,X,
01919769,HP17,S,S,5,5,
01919769,HP18,S,S,5, 5,
0797819,HP14,X,AX,X,X,
0797819,HP15,X,XA,X,X,
0797819,HP16,X,X,XA,XA,
0797819,HP17,A,A,X,X,
0797819,HP18,A,A,AX,X,

预期产出

假设我们想要 2 个大小相同的块。我想要如下 2 个文件,其中的密钥未在文件之间拆分。如果文件变大(更多行)以防止密钥分页,则可以。

文件 1

0190709,HP16,B,B,3,3,
0190709,HP17,B,B,3,3,
0190709,HP18,B,B,3,3,
0196597,HP11,,CaweNN,,,
0196597,HP119,, CNN,,,
0196597,HP13,,CNwN,,,
01919769,HP11,,AawNN,,,
01919769,HP119,,OePN,,,
01919769,HP13,,CNN,,,
01919769,HP14,XY,X,X, X,
01919769,HP15,A,A,XC,XA,
01919769,HP16,S,S,X,X,
01919769,HP17,S,S,5A,5,
01919769,HP18,S,S,5,5,

文件 2

0797819,HP14,X,AX,X,X,
0797819,HP15,X,XA,X,X,
0797819,HP16,X,X,XA,XA,
0797819,HP17,A,A,X,X,
0797819, HP18,A,A,AX,X,

4

1 回答 1

0

尽管您没有提供 CSV 文件的示例(前几行),但以下函数假定输入 csv 文件有效。

function Split-Csv {
    [CmdletBinding()]  
    Param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Path,          # the full path and filename of the source CSV file

        [Parameter(Mandatory = $true, Position = 1)]
        [string]$Destination,   # the path of the output folder

        [ValidateRange(1,[int]::MaxValue)]
        [int]$Chunks = 8,       # the number of parts to split into

        [switch]$FirstLineHasHeaders
    ) 
    # create the destination folder if it does not already exist
    if (!(Test-Path -Path $Destination -PathType Container)) {
        Write-Verbose "Creating folder '$Destination'"
        New-Item -Path $Destination -ItemType Directory | Out-Null
    }
    $outputFile = [System.IO.Path]::GetFileNameWithoutExtension($Path)
    $content    = Get-Content -Path $Path
    $totalLines = $content.Count

    if ($FirstLineHasHeaders) {
        $headers  = $content[0]
        $partsize = [Math]::Ceiling(($totalLines - 1) / $Chunks)
        for ($i = 0; $i -lt $Chunks; $i++) {
            $first   = ($i * $partsize + 1)
            $last    = [Math]::Min($first + $partsize -1, $totalLines - 1)
            $newFile = Join-Path -Path $Destination -ChildPath ('{0}-{1:000}.csv' -f $outputFile, ($i + 1))
            Write-Verbose "Creating file '$newFile'"
            Set-Content -Path $newFile -Value $headers -Force
            Add-Content -Path $newFile -Value $content[$first..$last]
        }
    }
    else {
        $partsize   = [Math]::Ceiling($totalLines / $Chunks)
        for ($i = 1; $i -le $Chunks; $i++) {
            $first   = (($i - 1) * $partsize)
            $last    = [Math]::Min(($i * $partsize) - 1, $totalLines - 1)
            $newFile = Join-Path -Path $Destination -ChildPath ('{0}-{1:000}.csv' -f $outputFile, $i)
            Write-Verbose "Creating file '$newFile'"
            Set-Content -Path $newFile -Value $content[$first..$last] -Force
        }
    }
}

如果您的输入 csv 文件有标题,您需要确保每个“块”文件也有这些标题。使用WITH开关功能$FirstLineHasHeaders

Split-Csv -Path 'C:\Test.csv' -Destination 'D:\test' -Chunks 8 -FirstLineHasHeaders -Verbose

如果您的输入 csv 文件没有标题,请像这样使用它:

Split-Csv -Path 'C:\Test.csv' -Destination 'D:\test' -Chunks 8 -Verbose
于 2019-09-16T12:09:14.153 回答