使用 PowerShell 限制 csv 列长度

Limit csv column length using PowerShell

我正在尝试使用 PowerShell 调整 tab-delimited 文本文件 而没有 headers 并将输出写入相同的 tab-delimited文本文件。目前源数据如下;

现在第三列应仅限于前 5 个字符,使输出如下所示;

我怎样才能做到这一点?

导入后截断:

Import-Csv ... | ForEach-Object { if ($_.Column3.Length -gt 5) { $_.Column3.Substring(0, 5) }; $_ }

如果您希望将规则应用于所有属性,您可以创建通用 属性 循环,而不是按名称定位特定 属性。

Import-Csv ... | ForEach-Object {
    foreach ($property in $_.PSObject.Properties) {
        if ($property.Value.Length -gt 5) {
            $property.Value = $property.Value.Substring(0, 5)
        }
    }
    $_
}

Import-Csv 本身不会为您做这些,这不是它接受培训的工作。

可以将自己的header信息传递给Import-Csv:

# Import the file with the proper delimiter and dummy headings
(Import-Csv foo.tsv -delim "`t" -header c1,c2,c3) |
  # Truncate the third column accordingly. Regex because I'm lazy.
  ForEach-Object { $_.c3 = $_.c3 -replace '(?<=^.{5}).*'; $_ } |
  # Convert back to TSV. This also emits the headers
  ConvertTo-Csv -NoTypeInformation -delim "`t" |
  # Remove the headers again
  Select -Skip 1 |
  # Write back to file
  Out-File foo.tsv -Encoding UTF8

以下代码将使用 Import-Csv 导入 CSV 文件,然后遍历所有行,在将行写入新的 CSV 文件之前创建第 3 列的子字符串(长度为 5)。

$oldCSV = "T:\OLD.csv"
$newCSV = "T:\New.csv" 

Import-Csv -Delimiter "`t" -Path $oldCSV -Header "1","2","3" | ForEach-Object { 
    "{0}`t{1}`t{2}" -f $_.1,$_.2,($_.3).Substring(0,[Math]::Min(5,($_.3).Length)) >> $newCSV 
}

更好的模块化方法是将修改后的对象通过管道传输到 Export-Csv commandlet。

$charLimit=100
Import-Csv "$_" -Delimiter "`t" | ForEach-Object {
   $_."column 1" = $_."column 1".Substring(0,[Math]::Min($charLimit,($_.'column 1').Length))
   $_."column 2" = $_."column 2".Substring(0,[Math]::Min($charLimit,($_.'column 2').Length))
   Write-Output $_
} | Export-Csv $targetfile -NoTypeInformation

在上面的代码片段中 Write-Output 会将修改后的对象向下传递到管道。这将比修改时写入更快,因为 Export-Csv 将比这更好地处理文件输出。