清理格式不正确的 csv 文件

cleanup improperly formatted csv file

我正在从共享点下载 xlsx 文件,然后将其转换为 csv 文件。但是,由于 xlsx 文件包含未删除的空列,因此它将这些列导出到 csv 文件,如下所示...

columnOne,columnTwo,columnThree,,,,
valueOne,,,,,,
,valueTwo,,,,,
,,valueThree,,,,

如您所见,由于额外的空标题,Import-Csv cmdlet 将无法处理该文件。我想知道如何计算最后多余的逗号。列的数量总是在变化,列的名称也总是在变化。所以我们从最后一个 non-null 标题编号开始计数。

现在,我正在做以下事情...

$csvFileEdited = Get-Content $csvFile

$csvFileEdited[0] = $csvFileEdited[0].TrimEnd(',')

$csvFileEdited | Set-Content "$csvFile-temp"
Move-Item "$csvFile-temp" $csvFile -Force
Write-Host "Trim Complete."

这将使文件输出如下...

columnOne,columnTwo,columnThree
valueOne,,,,,,
,valueTwo,,,,,
,,valueThree,,,,

Import-Csv 现在接受命名,但如您所见,仍然有额外的空值,这些空值不是必需的,因为它们对每一行都是空的。

如果我执行以下代码...

$csvFileWithExtraCommas = Get-Content $csvFile
$csvFileWithoutExtraCommas = @()

FOrEach ($line in $csvFileWithExtraCommas)
{
    $line = $line.TrimEnd(',')
    $csvFileWithoutExtraCommas += $line
{

$csvFileWithoutExtraCommas | Set-Content "$csvFile-temp"
Move-Item "$csvFile-temp" $csvFile -Force
Write-Host "Trim Complete."

然后它将删除一个空值,该值应该为空,因为它属于 non-null title-name。这就是输出....

columnOne,columnTwo,columnThree
valueOne
,valueTwo
,,valueThree

这是所需的输出:

columnOne,columnTwo,columnThree
valueOne,,
,valueTwo,
,,valueThree

有人可以帮忙吗?

更新

我正在使用以下代码来计算额外的空标题...

$csvFileWithCommas = Get-Content $csvFile

[int]$csvFileWithExtraCommasNumber = $csvFileWithCommas[0].Length

$csvFileTitlesWithoutExtraCommas = $csvFileWithCommas[0].TrimEnd(',')

[int]$csvFileWithoutExtraCommasNumber = $csvFileTitlesWithoutExtraCommas.Length

$numOfCommas = $csvFileWithExtraCommasNumber - $csvFileWithoutExtraCommasNumber

$numOfCommas的输出值为4。现在的问题是如何使用 $line.TrimEnd(',') 只这样做 4 次?

您在尝试 Import-csv 时遇到错误了吗?该 cmdlet 非常智能,无需任何额外代码即可忽略没有标题的列。

我将你的 csv 文件复制到我的 H:\ 驱动器:

columnOne,columnTwo,columnThree,,,,
valueOne,,,,,,
,valueTwo,,,,,
,,valueThree,,,,

然后 运行 $nullcsv = Import-Csv -Path H:\nullcsv.csv 这就是我得到的

PS> $nullcsv

columnOne columnTwo columnThree
--------- --------- -----------
valueOne
          valueTwo
                    valueThree

导入的 csv 仅包含 3 个值,如您所料:

PS> $nullcsv.count
3

该 cmdlet 还正确地解释了每一列中的空值:

PS> $nullcsv | Format-List

columnOne   : valueOne
columnTwo   :
columnThree :

columnOne   :
columnTwo   : valueTwo
columnThree :

columnOne   :
columnTwo   :
columnThree : valueThree

好的....如果你真的需要这样做,你可以计算 header 中的尾随逗号,并使用正则表达式从每行的末尾删除尽可能多的逗号。还有其他字符串操作方法,但本例中的正则表达式非常干净。

注意 Bluecakes answer 显示的内容应该足够了。也许问题中还有其他一些隐藏字符未被复制,或者您的真实文件可能存在编码问题。

$file = Get-Content "D:\temp\text.csv"
# Number of trailing commas. Compare the length before and after the trim
$numberofcommas = $file[0].Length - $file[0].TrimEnd(",").Length
# Use regex to remove as many commas from the end of each line and convert to csv object.
$file -replace ",{$numberofcommas}$" | ConvertFrom-Csv

正则表达式在每行末尾寻找 X 逗号,其中 X 是 $numberofcommas。在我们的例子中,它看起来像 ,{4}$


上面代码使用的源文件是这样生成的

@"
columnOne,columnTwo,columnThree,,,,
valueOne,,,,,,
,valueTwo,,,,,
,,valueThree,,,,
"@ | set-content D:\temp\text.csv