![](/img/trans.png)
[英]Powershell CSV removing rows and then remove from whole file if A column matches
[英]Script for removing rows based on entries from specific column in CSV file
我有一個這樣結構的文件(制表符分隔):
HEADER_1 HEADER_2
entry_A entry_A
entry_B entry_C
entry_A entry_D
entry_D entry_A
我需要做的是:每次第一列中的條目出現在第二列中時(在任何時候)刪除條目出現的整行
期望的輸出:
HEADER_1 HEADER_2
entry_B entry_C
entry_A entry_D
我嘗試使用Sort-Object -Unique
但輸出不正確,它只是刪除了重復的行
要輸出 Header_2 從不包含來自所有 Header_1 值的條目的行,您可以執行以下操作:
Windows PowerShell:
$data = Import-Csv file.csv -Delimiter "`t"
($data | where Header_1 -notin $data.Header_2 |
ConvertTo-Csv -NoType -Delimiter "`t") -replace '^"|"$|"(\t)"','$1' |
Set-Content file.csv
PowerShell 7:
$data = Import-Csv file.csv -Delimiter "`t"
$data | where Header_1 -notin $data.Header_2 |
Export-Csv -NoType -Delimiter "`t" -UseQuotes AsNeeded
我覺得你想要做的是輸出 Header_2 尚未作為 Header_1 值出現的行,這意味着你忽略了未來的 Header_1 值。
$list = [system.collections.generic.list[string]]@()
(Import-Csv file.csv -delimiter "`t" | Foreach-Object {
$list.Add($_.Header_1)
if ($_.Header_2 -notin $list) {
$_
}
} | ConvertTo-Csv -NoType -Delimiter "`t") -replace '^"|"$|"(\t)"','$1' |
Set-Content file.csv
您可以在不使用*-Csv
命令的情況*-Csv
一條路線,然后您就不必處理 PowerShell 非核心版本的限定文本。
$list = [system.collections.generic.list[string]]@()
Get-Content file.csv | Foreach-Object {
$h1,$h2 = $_ -split '\t'
$list.Add($h1)
if ($h2 -notin $list) {
$_
}
} | Set-Content file.csv
您還可以使用 .NET System.Collections.Generic.HashSet
類通過Contains()
進行 O(1) 查找:
$data = Import-Csv -Path file.csv -Delimiter "`t"
$hashSet = New-Object -TypeName System.Collections.Generic.HashSet[string]
$keep = @()
foreach ($row in $data)
{
$hashSet.Add($row.HEADER_1)
if (-not($hashSet.Contains(($row.HEADER_2))))
{
$keep += $row
}
}
$keep | Export-Csv -Path file.csv -Delimiter "`t" -NoTypeInformation
這會產生一個新的file.csv
:
"HEADER_1" "HEADER_2"
"entry_B" "entry_C"
"entry_A" "entry_D"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.