【问题标题】:Loop through a CSV file and verify column count for each row循环遍历 CSV 文件并验证每行的列数
【发布时间】:2016-09-28 19:42:35
【问题描述】:

我是 PowerShell 新手,一直在尝试遍历 CSV 文件并返回每行的列数。将该列数与第一行进行比较,并发生不相等的事情。在这种情况下,将逗号替换为空。然后创建一个包含更改的新文件。

$csvColumnCount = (import-csv "a CSV file" | get-member -type NoteProperty).count

$CurrentFile = Get-Content "a CSV file" |
ForEach-Object { $CurrentLineCount = import-csv "a CSV file" | get-member -type NoteProperty).count
    $Line = $_ 
    if ($csvColumnCount -ne $CurrentLineCount)
         { $Line -Replace "," , "" }
    else
         { $Line } ; 
    $CurrentLineCount++} | 
Set-Content ($CurrentFile+".out")
Copy-Item ($CurrentFile+".out") $ReplaceCSVFile

【问题讨论】:

  • 那么什么不起作用?
  • 我认为它没有正确计算每行的列数。我正在使用的测试 CSV 文件有几行少于标题行列。该脚本正在删除整个文件中的逗号。
  • 您想测试一行中的任何属性是否为空或缺失?然后改变那些行?
  • 抱歉,不确定您所说的属性是什么意思。我只想测试列数。即如果文件中的第一行有 8 列(标题行)并且第 10 行只有 9 列,我只想更改第 10 行。
  • 您想要达到的目标对我来说并不明显。似乎目的是检测其上值不足的行。然后这些行删除所有逗号,有效地将它们变成单值行。生成的文件将是“好”行和具有单个值的行的混合。这真的是你想要的吗?

标签: csv powershell


【解决方案1】:

如果您的目的是检查 CSV 文件的哪些行无效,那么只需使用简单的拆分和计数,如下所示:

$csv = Get-Content 'your_file.csv'
$count = ($csv[0] -split ',').count
$csv | Select -Skip 1 | % {
  if(($_ -split ',').count -eq $count) {
    ...do valid stuff
  } else {
    ...do invalid stuff
  }
} 

出于 CSV 检查目的,请避免使用 CSV cmdlet,因为这些 cmdlet 倾向于尝试纠正问题,例如:

$x = @"
a,b,c
1,2,3,4
"@

$x | ConvertFrom-Csv

>  a b c
   - - -
   1 2 3

另外,我认为您的代码流程有点混乱。您尝试将管道的结果返回到名为 $CurrentFile 的变量,而在该管道的另一端,您尝试使用相同的变量作为 Set-Content 的文件名。

如果您的 CSV 包含可能包含逗号的引用字段,那么简单的拆分将不起作用。如果是这种情况,更好的选择是使用正则表达式将每行分成可以计算的列。像这样:

$re = '(?:^|,)(?:\"(?:[^\"]+|\"\")*\"|[^,]*)'
$csv = Get-Content 'your_file.csv'
$count = [regex]::matches($csv[0], $re).groups.count
$csv | Select -Skip 1 | % {
  if([regex]::matches($_, $re).groups.count -eq $count) {
    ...do valid stuff
  } else {
    ...do invalid stuff
  }
}

【讨论】:

  • 代替$csv[1..($csv.count - 1)] .... $csv | Select -Skip 1 | % 似乎更简单
  • @Dave Sexton 感谢您的回复!但是,我认为上面的代码行不通,因为我不能简单地计算 CSV 文件中的逗号。如果单元格中有逗号,则 CSV 文件将用引号将单元格括起来。 import-csv 似乎返回了第一行的正确计数,问题似乎是循环遍历每一行。
  • 修改我的答案以处理引号中的逗号。
猜你喜欢
  • 2017-10-02
  • 2014-04-10
  • 2017-09-08
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 2023-02-24
  • 2021-03-04
  • 1970-01-01
相关资源
最近更新 更多