別のファイルを使用して一致する列を持つパイプで区切られたファイルから行を削除するPerlスクリプト

別のファイルを使用して一致する列を持つパイプで区切られたファイルから行を削除するPerlスクリプト

パイプ()で区切られた列のすべてのレコードをFile A含む2つの巨大なファイルがあり、そのファイルには1つの列しかありません。|File B

File Aその列の値が一致するすべての行を削除する必要がありますFile B

ファイルBの列1をファイルAの列2と比較したいと思います。

FileB - fileBの唯一の列

818815504
842019301
880702511

FileA - FileAの2番目の列

2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|818815504|2|15|1|403933|8|2394063|3036|2394067|4076948618|0|15177438|B|1168|CRU|98|NK
2020-01-19|842019301|2|15|1|2|2|3712|3036|961249|65707843|65707843|8591573|B|1168|IRU|1|NJ
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

答え1

結果の順序は重要ではないと仮定します。

$ join -v 1 -t '|' -1 2 <( sort -t '|' -k2,2 fileA ) <( sort fileB )
777504559|2020-01-19|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
847082255|2020-01-19|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
858760375|2020-01-19|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR
858760375|2020-01-19|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
869323039|2020-01-19|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
872268371|2020-01-19|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR

このjoinユーティリティーは、指定された 2 つのデータ・セットに対してリレーショナル INNER JOIN 操作を実行します。データセットは、私たちが結合する列に基づいてソートする必要があり、これが呼び出される前にファイルをソートする理由ですjoin(シェルがプロセスオーバーライドをサポートしていない場合は、別々にファイルをソートしてください)。joinここで使用するオプション-t '|'は、-1 2|列区切り文字として使用し、最初のデータセットの2番目の列にリンクする」ことを意味します(そうでなければ、最初の列はデフォルト値です)。

-v 12番目のファイルの行とペアにできない最初のファイルのすべての行を要求します。

出力には常に結合列が最初にリストされているため、最初の2つの列を次のように置き換えて正しい位置に移動できますawk

$ join -v 1 -t '|' -1 2 <( sort -t '|' -k2,2 fileA ) <( sort fileB ) | awk 'BEGIN { FS=OFS="|" } { t=$1; $1=$2; $2=t; print }'
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR

以下のみを使用してくださいawk

$ awk -F '|' 'FNR==NR { key[$1]=1; next } !($2 in key)' fileB fileA
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

まず、連想配列に抽出したい数字を読みますkey。次に、2番目のファイルを解析するときに、2番目のフィールドがその配列のキーではない場合は、その行を印刷します。

これは、そのファイルに表示される順序で行を出力しfileAますが、すべての数字をfileBメモリに保持する必要があるという欠点があります。


リクエストに応じてPerlを使用してください。

$ perl -F'\|' -le 'if (!$flag){ $key{$F[0]}=1 } elsif ($key{$F[1]}!=1) { print $_ }; if (!$flag && eof) { $flag=1 };' fileB fileA
2020-01-19|777504559|2|15|1|403941|53|4708267|3036|5033|127380343|0|3905585|C|1168|IRU|107|NR
2020-01-19|847082255|2|15|1|2|2|284|3036|291|125650195|125650195|8870299|C|1168|IRU|1|NR
2020-01-19|858760375|2|15|1|403941|53|4708267|3036|306|99931425|0|8866849|C|1168|IRU|107|NR
2020-01-19|869323039|2|15|1|2|2|371|3036|307|106104029|106104029|4518435|C|1168|IRU|2|NR
2020-01-19|872268371|2|15|1|403941|53|4708267|3036|143|127382679|0|8866849|C|1168|IRU|107|NR
2020-01-19|858760375|2|15|1|2|2|117|3036|109|2739523|5208959|4037061|C|1168|IRU|2|NR

これはプログラムを模倣しますが、Perlには別の組み込み変数がawkないため、現在最初のファイルを解析しているのか、それとも2番目のファイルを解析しているのかを示すいくつかの状態()を維持する必要があります。NRFNR$flag

関連情報