ファイルから重複レコードを削除し、一意の識別子を無視します。

ファイルから重複レコードを削除し、一意の識別子を無視します。

28フィールド/ヘッダー/プロパティ(カンマ区切り)を含むファイルがあります。フィールド#はレコードを一意にします。ただし、残りのフィールドは同じにすることができます。重複した項目を見つけて1つだけ保管する必要があります。 2回目の反復よりも1回目の反復を維持する方が簡単な場合は問題ありません。例:

入力ファイル:

1,ed23,jon,doe,director,usa
2,ed23,jon,doe,director,usa
3,er67,jake,Kogan,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

希望の出力:

2,ed23,jon,doe,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

ベストアンサー1

入力例は混乱しています。最初の行(列見出し)にはフィールド区切り記号のコンマも含まれておらず、ほとんどの行には成績と成績フィールドの間にカンマがありません。

少し健全な入力を提供するために、次のように編集しました。

$ cat input.txt 
ID, uid  ,firstname ,lastname,   grade    , country n28
1 , ed23 , jon     ,   doe   ,  director  ,  usa
2 , ed23 ,  jon     ,  doe   ,  director     , usa
3 , er67 ,  jake     , Kogan ,  director     , usa
4 , er67 ,  jake     , Kogan ,  director     , usa
5 , dc10 ,  Charls     ,Morg ,  manager      , usa
6 , kc56 ,  patel     ,Kumar ,  associate    , india

チートを削除する簡単な実装は次のとおりです。

$ awk -F' *, *' -v OFS=, \
    'NR==1 {$1=$1;$0=$0; print; next};
     {id=$1; $1=""; $0=$0; if (!seen[$0]++) {print id $0}}' input.txt 
ID,uid,firstname,lastname,grade,country n28
1,ed23,jon,doe,director,usa
3,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

これは、入力フィールド区切り文字(FS)を0個以上のスペースに設定し、その後にカンマ、0個以上のスペースを設定し、OFS出力フィールド区切り文字()をコンマのみに設定します。つまり、すべてのフィールドで前後のスペースを効果的に削除します。

最初の入力行(NR==1)の場合は、awkトリックを使用して入力行の形式を再指定します。つまり、フィールドを変更(元の値に設定)を設定します$0=$0。行は新しいOFSを使用するように再フォーマットされます。その後、印刷して次の行に移動します。

残りの入力では、$ 1という変数に$ 1をid空の文字列に設定し、$0=$0IDと行の残りの部分を印刷する前にトリックを再利用します(行から$ 1を効果的に削除します)。

出力例とは異なり、以下は印刷されます。最初最後の行ではなく重複した行 - 最初に見たときは検出しやすいが、最後に見たときは検出しにくい(入力内容をすべて読まないと不明)。また、これは反復回数をカウントしません。

これらの両方を行うには、出力を生成する前に入力ファイル全体を読み、2番目の配列(重要な行にすることもできます)ids

$ awk -F' *, *' -v OFS=, \
   'NR==1 {$1=$1;$0=$0",count";print;next};
   {id=$1; $1=""; $0=$0; seen[$0]++; ids[$0]=id};
   END { for (id in ids) {print ids[id] id, seen[id]} }' input.txt  | \
 sort -n
ID,uid,firstname,lastname,grade,country n28,count
2,ed23,jon,doe,director,usa,2
4,er67,jake,Kogan,director,usa,2
5,dc10,Charls,Morg,manager,usa,1
6,kc56,patel,Kumar,associate,india,1

sort -nこれは、awkの連想配列が順序がないため、半ランダムな順序で表示されるために使用されます。 GNU awkには、配列に使用asort()できる値で配列を並べ替える関数がありますが、idsa)移植性がなく、b)出力をsort -n

おすすめ記事