尋找 CSV 中重複的列值

尋找 CSV 中重複的列值

我試圖從一個大的 csv 檔案中找到重複的 id,每行只有記錄,但查找重複的條件將是第一列。<id>,<value>,<date>

範例.csv

11111111,high,6/3/2019
22222222,high,6/3/2019
33333333,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019

期望的輸出:

11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019

輸出不需要順序。

答案1

使用 AWK:

awk -F, 'data[$1] && !output[$1] { print data[$1]; output[$1] = 1 }; output[$1]; { data[$1] = $0 }'

它會查看每一行,其行為如下:

  • 如果我們已經看到第一列中的值,請注意,我們應該輸出與該值相符的任何行,並輸出記憶的行;
  • 如果當前行的第一列與我們想要輸出的匹配,則輸出目前行;
  • 儲存在第一列上鍵入的目前行。

答案2

如果所有 ID 的長度相同(範例中為 8 個字元),則可以使用sortGNU完成整個操作uniq

$ sort file | uniq -Dw 8
11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019

如果它們的長度不同,您仍然可以使用此方法,但它會變得有點複雜:

$ tr ',' ' ' < file | sort  | rev | uniq -f2 -D | rev | tr ' ' ','
11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019

答案3

awk -F, '$1 in m { print m[$1]$0; m[$1]=""; next } 
                 { m[$1]=$0 "\n" }' ex

答案4

GNU sed這可以透過利用其擴展的正則表達式構造來完成。我們首先將檔案載入到模式空間中,然後從模式空間的開頭刪除所有不重複的行。此外,一個標誌\n\n,被放置在模式空間的末尾,我們在其中覆蓋重複的行。因此,一旦該標誌冒泡到模式空間的開頭 => 操作就結束了,我們現在可以繼續從模式空間中刪除標記並列印到標準輸出。

$ sed -Ee '
   $!{
      N;s/^/\n/
      $s/$/\n\n/;D
   }
   /^([^,\n]*),[^\n]*\n(.*\n)?\1,/!D
   s/^([^\n]*)(.*)/\2\1\n/;/^\n\n/!D
   s/^\n\n//;s/\n$//
' inp

這是POSIX-sed解決問題的一個版本和另一種方法,即我們不在模式或保留空間中的任何時間點來維護整個文件。一旦看到重複行,就會將其列印到標準輸出,並且參考行被標記並列印,標記是因為我們不想在下次看到重複行時列印它。

$ sed -ne '
   H;g;y/\n_/_\n/
   /.*_\([^,_]*\)\(,[^_]*\)\[0]_\(.*_\)\{0,1\}\1,[^_]*$/{
      s//\1\2/;y/_\n/\n_/;p
      g;s/.*\n//p;g;y/\n_/_\n/
      s/\(.*_\([^,_]*\),[^_]*\)\[0]\(_\(.*_\)\{0,1\}\)\2,[^_]*$/\1[1]\3/
      s/_$//;y/_\n/\n_/;bh
   }
   /.*_\([^,_]*\)\(,[^_]*\)\[1]_\(.*_\)\{0,1\}\1,[^_]*$/{
      s/.*_//;y/_\n/\n_/;p
      g;s/\(.*\)\n.*/\1/;bh
   }
   y/_\n/\n_/;s/$/[0]/;:h;h
' inp

這是解決Perl我們在數組雜湊中維護行的問題的基礎解決方案。一旦我們看到重複的行,我們就會列印數組並清空它,並列印重複的行。

$ perl -F, -lane '
   push(@{$h{$F[0]}},$_),next if ! exists $h{$F[0]};
   print for splice(@{$h{$F[0]}}),$_;
' inp

輸出:

11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019

相關內容