2016-05-30 38 views
1

我是PowerShell的新手,一直試圖循環訪問CSV文件並返回每一行的列數。將該列數與第一行進行比較,發現它不相等。在這種情況下,用逗號替換逗號。然後創建一個包含更改的新文件。循環遍歷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 
+0

那麼有什麼不工作? – DeanOC

+0

我認爲它不包括每行正確的列數。我正在使用的測試CSV文件的行數少於標題行列。該腳本正在刪除整個文件中的逗號。 – leo

+0

你想測試一行中的任何屬性是空的還是缺失?然後改變這些行? – xXhRQ8sD2L7Z

回答

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的,因爲這些將有嘗試和糾正問題的傾向,例如:

$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 
    } 
} 
+0

代替'$ csv [1 ..($ csv.count - 1)]'....'$ csv |選擇-Skip 1 | %'似乎簡單得多 – Matt

+0

@Dave Sexton感謝您的回覆!但是,我不認爲上面的代碼會起作用,因爲我不能簡單地在CSV文件中計算逗號。如果單元格中有逗號,則CSV文件將用引號括住單元格。 import-csv似乎爲第一行返回正確的計數,問題似乎是循環遍歷每一行。 – leo

+0

修改我的答案,以處理引號中的逗號。 –