ファイルに逆行がある場合にファイルからその行を削除するコマンド

ファイルに逆行がある場合にファイルからその行を削除するコマンド

次のCSVがあると言えます。

1,20
1,13
20,1

1,20がすでにcsvにあるため、20,1を削除する必要があります。私の考えは、リバースコンテンツがすでにcsvにあることを1行ずつ確認することですが、シェルスクリプトを使用してこれを行う方法がわかりません。

編集:2つの同じ数字を同じ行に含めることはできません。たとえば、20,20 は決して表示されません。

答え1

これを合理的な速度で達成するには、ある種のハッシュテーブルが必要です。従来はこれを行いますawkが、bash連想配列を含むすべての最新のスクリプト言語でこれを実行できます。

awk 'BEGIN{FS=","}                                                                   
{                                                                               
   rev=$NF; for(i=NF-1;i>0;i--) {rev = rev "," $i}                                                                         
   if (!seen[rev]) { print }                                                    
   seen[$0]=1                                                               
}'

これはrevに逆行を構成し、まだ見たことがない場合は逆行を印刷してから、見たものを記録します。

答え2

$ cat file
4,bumblebee
1,20
1,13
20,1
20,1
20,13
bumblebee,3
13,1
bumblebee,4
$ awk -F, '!seen[$1,$2]++ && !seen[$2,$1]' file
4,bumblebee
1,20
1,13
20,13
bumblebee,3

seenこれは、入力にフィールドペアが表示される回数を数える連想配列を使用して行われます。

以前にそのペアや反対のペアを見たことがない場合は、その行を印刷してください。

これは、フィールドが数値であるとは仮定しません。

答え3

実際に、目的の部分が順序に関係なく特定の部分の組み合わせが一度だけ表示されるようにすることを前提として、慣用的なアプローチは、一意にしたい部分を特定の順序で並べ替え、結果が表示されることを確認することです。鍵は以前見たことがあります。部品が2つしかない場合は、次のようになります。

$ awk -F',' '!seen[$1>$2 ? $1 FS $2 : $2 FS $1]++' file
1,20
1,13

関連情報