0

(これはおそらく私が見逃しているかなり単純なものです;しかし、私はそれを理解できないようで、検索で答えが見つかりませんでした)

同じ列を持つ 2 つの CSV ファイルを比較し、次のように行の違いを出力する必要があります (Unicode テキストの最終出力)。

  • 行が FileA に存在するが FileB に存在しない場合、その行に「良好」というラベルを付けます。
  • 行が FileB に存在するが FileA に存在しない場合、その行に「Bad」というラベルを付けます。

次のサンプルデータがあるとします。

File A:
Column1,Column2,Column3
Tommy,4133,20180204
Suzie,5200,20210112
Tammy,221,20201010

File B:
Column1,Column2,Column3
Tommy,4133,20180204
Nicky,5200,20190520

これが私の現在のコードです(提供されたCompare-Objectが遅すぎるため、このサイトからハッシュ対応のCompare-Object2を借りています-参考までに、50倍高速であるため、Import-Csvの代わりにGet-Contentを使用しています行全体を比較しているため、 MyHeader 変数は元のファイルのヘッダー列の値を保持するためのものです)

Compare-Object2 (Get-Content $FileA) (Get-Content $FileB) -PassThru |
Select-Object @{l=[string]$MyHeader;e={$_.InputObject}},
              @{n='Row Label'; e={ @{'=>' = 'Bad' ; '<=' = 'Good'}[$_.SideIndicator]}},
              @{n='Placeholder'; e={@{'*'='0'}['*']}} |
Sort-Object 'Row Label' -Descending | Export-Csv "$FinalCSV" -NoType;

#Removing " char to create CSV with original and added columns together
Set-Content "$FinalCSV" ((Get-Content "$FinalCSV") -replace '"');

#Convert csv to tab delimited
Import-Csv "$FinalCSV" | Export-Csv "$FinalTXT"  -NoTypeInformation -Delimiter "`t";

#Remove " char and convert to unicode
Set-Content -Encoding UNICODE "$FinalTXT" ((Get-Content "$FinalTXT") -replace '"')

これは完全に機能します (一部は最後に冗長であることはわかっています。でも、これが私にできる最善の方法です。ただし、これらの部分も自由に修正してください!)、良い部分と悪い部分の単一の出力ファイルを作成します。 - 400K 行の 2 つのファイルで約 40 秒。

Result File:
Column1 Column2 Column3 Row Label   Placeholder
Suzie   5200    20210112    Good    0
Tammy   221 20201010    Good    0
Nicky   5200    20210112    Bad 0

問題は、それらを個別のファイルとして作成する必要があることです。1 つのファイルは良いファイルで、もう 1 つは悪いファイルです。したがって、新しく必要な出力は次のようになります。

ResultFileGood:
Column1 Column2 Column3 Row Label   Placeholder
Suzie   5200    20210112    Good    0
Tammy   221 20201010    Good    0

ResultFileBad:
Column1 Column2 Column3 Row Label   Placeholder
Nicky   5200    20210112    Bad 0

そして、比較を2回実行することなくそれを行う方法が必要であることを知っています-Where-Objectプロップまたは何らかのループを使用します。私はそれを理解できません。だから私は専門家に来ています。

ありがとう

編集: postanote のおかげで、実行可能な代替手段の 1 つは、結合されたファイルを出力してから分割することです。これは、比較ルーチン全体を 2 回実行するよりも確実に高速です。中間ファイルなしで比較エクスポートで直接行う方法があるかどうかを確認したいと思います。しかし、それは間違いなく実行可能なオプションであり、私が現在使用しているものです

$FinalHeader = get-content "$FinalTXT" | Select -First 1
$BadOutput = Select-String -Path $FinalTXT -Pattern ('Bad   0')
$GoodOutput = Select-String -Path $FinalTXT -Pattern ('Good 0')
@($FinalHeader,$BadOutput.Line) | Out-File "$FinalBadTXT" -Encoding UNICODE;
@($FinalHeader,$GoodOutput.Line) | Out-File "$FinalGoodTXT" -Encoding UNICODE;
4

1 に答える 1