使用 powershell 处理多个 CSV 文件并删除具有双分号字符的单列中的行

process multiple CSV file and delete rows in a single column which has double semi colon characters using powershell

考虑一下我有一个 CSV 文件。

输入:

ID;ITEM_ID;STATUS;
001;;RELEASED;
002;36530;RELEASED;
003;86246;RELEASED;
004;;RELEASED;

我想删除包含 ;; 的行(ITEM_ID) missing and save it.I 尝试在一个示例文件上执行此操作并且按预期工作。

Import-Csv -Path ".\TestFile.CSV" | where {$_.ITEM_ID -ne ""} | Export-Csv -Path ".\TestFile-temp.CSV" -NoTypeInformation
Remove-Item -Path '.\TestDir\TestFile.csv'
Rename-Item -Path '.\TestDir\TestFile-temp.csv' -NewName 'TestFile.csv'

输出:

ID;ITEM_ID;STATUS;
002;36530;RELEASED;
003;86246;RELEASED;

挑战是,我有多个 csv 文件,它在不同的列中没有价值,但是当我在 excel 文件中打开时在单个列中。 所以它不采用条件 < where {$_.ITEM_ID -ne ""} >。 现在我必须 search/parse 每个 csv 文件的每一行,在该行中搜索特殊字符 (;;) 并删除该行并保存文件。

我擅长 shell 脚本编写,但是我对 powershell 脚本编写还很陌生。任何人都可以帮助我在这里获得逻辑或使用其他可以完成这项工作的 cmdlet 吗?

$fileDirectory = "C:\Users\Administrator\Documents\check";
foreach($file in Get-ChildItem $fileDirectory)
{
    $csvFileToCheck = Import-Csv -Path $fileDirectory$file
    $noDoubleSemiComma = foreach($line in $csvFileToCheck)
            {
                if(Select-String << i want the logic here>>)
                {
                $line
                }               
            }
    $noDoubleSemiComma | Export-Csv -Path $fileDirectory\tmp.csv -NoTypeInformation
    Remove-Item -Path $fileDirectory$file
    Rename-Item -Path $fileDirectory\tmp.csv -NewName $file
}

经过所有有用的建议,我终于确定下来了。由于我的 power-shell 版本是 5.1 ,我不得不在 export-csv 之后使用 trimming 双引号的逻辑。 Powershell 版本 7 及更高版本的 -UseQuotes 也可以解决这个问题。 希望这对其他人有帮助。

$fileDirectory = "C:\Users\Administrator\Documents\check";
foreach($file in Get-ChildItem $fileDirectory)
{
        Import-Csv -Path $fileDirectory$file -Delimiter ';' | where {$_..ITEM_ID -ne ""} | Export-Csv -Path $fileDirectory\temp.csv -Delimiter ';' -NoTypeInformation
        $Test = Get-Content $fileDirectory\temp.csv
        $Test.Replace('";"',";").TrimStart('"').TrimEnd('"') | Out-File $fileDirectory\temp.csv -Force -Confirm:$false
        Remove-Item -Path $fileDirectory$file
        Rename-Item -Path $fileDirectory\temp.csv -NewName $file
        Write-Output "$file file modified."
}

欢迎任何trim减少代码行数的建议。

如评论所述,您需要向 cmdlet 添加参数 -Delimiter ';',否则将使用逗号来解析 CSV 中的字段。

据我所知,您还想删除所有字段和 headers 周围的引号 Export-Csv 输出,对于 PowerShell 版本 7,您可以选择使用参数 -UseQuotes AsNeeded

由于这不适用于 5.1 版,我前段时间做了一个函数 ConvertTo-CsvNoQuotes 以安全的方式删除引号。 (简单地将它们全部替换为空字符串是危险的,因为有时值确实需要引号)

将该函数复制到顶部的脚本中,然后在其下方,您的代码可以像这样简化:

$fileDirectory = "C:\Users\Administrator\Documents\check"

Get-ChildItem -Path $fileDirectory -Filter '*.csv' -File | ForEach-Object {
    # for better readability store the full path of the file in a variable
    $filePath = $_.FullName
    (Import-Csv -Path $filePath -Delimiter ';') | ConvertTo-CsvNoQuotes -Delimiter ';' | Set-Content $filePath -Force
    Write-Host "File '$filePath' modified"
}