簡體   English   中英

如何從Powershell中的多個csv文件中刪除特定行?

[英]How to delete specific rows from multiple csv files in powershell?

您好,我正在尋找一種從多個csv文件刪除第二行和最后一行的有效方法? 我的目錄中大約有5000個文件。 下面的代碼將刪除第一行。 如果使用參數-skip 2,它將跳過前2行,但是我需要保留第一行,並刪除第二行和最后一行。 我也不確定get-content set-content是否是處理如此大量文件的正確方法。

foreach ($file in gci *.csv ){
(gc $file) | Select-Object -Skip 1 | set-content $file
 }

只需說一下性能。 我使用@TheMadTechnician方法獲取內容,並比較了3種不同的編寫輸出方法。 我為每個測試使用了100個1MB的輸入文件。 結果如下:

使用Out-File覆蓋內容需要1分32秒。

dir *.txt | %{
    $content = gc $_.FullName
    $content | select -First 1 | Out-File $_.FullName -Force
    $content[2..($content.count -2)]|Out-File $_.FullName -Append
}

使用Set-Content覆蓋內容花費了37秒。

dir *.txt | %{
    $content = gc $_.FullName
    $output = @($content | select -First 1 )
    $output += $content[2..($content.count -2)]
    $output | Set-Content $_.FullName -Force
}

使用StreamWriter覆蓋內容花費了31秒。

dir *.txt | %{     
    $content = gc $_.FullName
    $output = @($content | select -First 1 )
    $output += $content[2..($content.count -2)]
    $sw = New-Object System.IO.StreamWriter($_.FullName,$false)
    $output | %{$sw.WriteLine($_)}
    $sw.close()
}

您可能想針對您的特定情況研究這些不同的方法,但是我始終發現Out-File比Set-Content或StreamWriter慢得多。

也許不是最好的方法,但是您可以使用-Index並計算所需的行。

foreach ($file in gci *.csv ){
    $data = gc $file
    $data | Select-Object -Index (,0 + (2..($data.Count - 2))) | set-content $file
}

對於數組,索引從0開始,因此我們取其中一個並跳過記錄1。之后,我們取其余減去最后一個。 -Index采用和整數數組,因此我們創建一個值為0的單元素數組,並將索引從2追加到文件末尾減去最后一個(這是-2 ,因為.Count從1開始)。

您接近了,我只是通過代碼中的Where子句來跳過每個文件中的項目1和項目-1。 像這樣:

(gci *.csv )|ForEach{
    $file = $_
    $contents = gc $file
    $contents | Where{$_ -ne $contents[1] -and $_ -ne $contents[-1]} | out-file $file.fullname -force
}

我進行了ForEach內聯操作,以確保GCI完成並且在嘗試執行Out-File時沒有保持打開狀態

編輯:我剛剛意識到我的代碼有一個潛在的缺陷,即如果您對第2行或最后一行重復行,那么這些行也將被消除。 我寫這篇文章的前提是您想要清理以下內容:

Col1,Col2,Col3,Col4
---- ---- ---- ----
Data,data,data,data
data,data,data,data
Log Created: 02/04/2015

您要刪除---行的地方,並在日志末尾創建了日志。

Edit2:更好的解決方案可能是獲取文件的內容,輸出第一行,然后從末尾輸出第3行(減去1行)並將其附加到同一文件中。 就像是:

(gci *.csv )|ForEach{
    $Path = $_.FullName
    $content = gc $Path
    $content|select -first 1|Out-File $Path -force
    $content[2..($content.count-2)]|Out-File $Path -Append
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM