重複文字列を含む行を削除する

重複文字列を含む行を削除する

特定のパターン/文字列のファイルを確認し、すべての列に存在する場合はその行を削除したいと思います。

例:

name1   name2   name3   name1   name1   name2   name3
name1   name2   name3   name1   name2   name1   
name2   name1   name1   name2   name3   name1   
name2   name2   name2   name2   name2   

このファイルでは、行4のすべての列に同じ名前が含まれているので、行4を削除したいと思います。

大容量ファイルがあり、awkまたはgrepで列数を手動で定義することはできません。

答え1

そしてawk

awk 'NF>1 { for(i=2; i<=NF; i++) if($i != $1) { print; next } } NF<=1' file

sedGNUまたは最近BSDを使用するsed

sed -E '/^[ \t]*([^ \t]+)([ \t]+\1)+[ \t]*$/d' file

答え2

そしてperl

$ perl -lane '(@a) = /$F[0]/g; print if $#F != $#a' file 
name1   name2   name3   name1   name1   name2   name3
name1   name2   name3   name1   name2   name1   
name2   name1   name1   name2   name3   name1   
  • 入力行をスペースに分割
  • 最初の列がパターンとして使用され、フィールド数が一致数と等しい場合、行は印刷されません。


grepファイルの各列の後に常に同じ数のスペースがある場合:

$ grep -vxE '(\S+\s+)\1*' file 
name1   name2   name3   name1   name1   name2   name3
name1   name2   name3   name1   name2   name1   
name2   name1   name1   name2   name3   name1   


メモ:単一の列行が出力の一部である必要がある場合は、次のようにします。

perl -lane '(@a) = /$F[0]/g; print if $#F != $#a || $#F == 0' file 

そして

grep -vxE '(\S+\s+)\1+' file 

答え3

Perlでこれを行うもう1つの方法は、フィールドをハッシュにマップし、スカラーコンテキストで評価して結果キーを計算することです。

$ perl -ane '%names = map { $_ => 1 } @F; print unless keys %names == 1' example
name1 name2 name3 name1 name1 name2 name3
name1 name2 name3 name1 name2 name1
name2 name1 name1 name2 name3 name1

または、より簡単に匿名ハッシュを使用してください。

$ perl -ane 'print unless keys %{ {map { $_ => 1 } @F } } == 1' example
name1 name2 name3 name1 name1 name2 name3
name1 name2 name3 name1 name2 name1
name2 name1 name1 name2 name3 name1

関連情報