一部の行にコメントを付けるか、最初に別のタグを付けることができますが、テキストファイルで重複した行を見つける方法は何ですか?

一部の行にコメントを付けるか、最初に別のタグを付けることができますが、テキストファイルで重複した行を見つける方法は何ですか?

次のように行が混在するテキストファイルがあります。

###  Comments

# Comments
86.242.200.81 banana.domain.net          # comment
86.242.200.3 orange.domain.net
31.28.225.81 monkey.anotherdomain.net

51.18.33.4 puffin.domainz.com
#31.28.220.80 monkey.anotherdomain.net   # comment
86.242.201.3 orange.domain.net

重複したホストドメインを見つける方法は?

monkey.anotherdomain.netこの場合は2つあります。 orange.domain.net

これを念頭に置いて...

  • 項目の後のコメントは重複しない可能性があるため、無視する必要があります。
  • その行をコメントアウトしても、重複した行が見つかるはずです。
  • IPアドレスの違いは無視する必要があります。

答え1

興味深いです。

まず、削除する必要があります。続く次のコメント:

86.242.200.81 banana.domain.net          # comment

次のコマンドを使用してこれを行うことができます(スペースのみがあり、タブはないと仮定)。

sed 's/  *#.*//'

ホストファイルにタブがある場合は、まず次のコマンドを実行できます。

tr '\t' ' '

次に、IPアドレスの前にある単一のハッシュ文字で定義されている「この行をコメントとして扱う」コメントを削除する必要があります。次のように削除できます。

sed '/^#[0-9]/ s/^#//'

上記をまとめると次のようになります。

###  Comments

# Comments
86.242.200.81 banana.domain.net
86.242.200.3 orange.domain.net
31.28.225.81 monkey.anotherdomain.net

51.18.33.4 puffin.domainz.com
31.28.220.80 monkey.anotherdomain.net
86.242.201.3 orange.domain.net

2番目の列()をソートすると、名前でソートされたsort -k2リストが表示されます。

86.242.200.81 banana.domain.net
# Comments
###  Comments
31.28.220.80 monkey.anotherdomain.net
31.28.225.81 monkey.anotherdomain.net
86.242.200.3 orange.domain.net
86.242.201.3 orange.domain.net
51.18.33.4 puffin.domainz.com

最初のフィールドを無視するように指示すると、重複するuniq項目の検索を適用できます。uniq

uniq -c -f 1

これは私たちに以下を提供します。

  2 
  1 86.242.200.81 banana.domain.net
  1 # Comments
  1 ###  Comments
  2 31.28.220.80 monkey.anotherdomain.net
  2 86.242.200.3 orange.domain.net
  1 51.18.33.4 puffin.domainz.com

したがって、数が2以上の行を見つけると、重複した項目が見つかります。これをまとめると、次のような結果が得られます。

#!/bin/sh

tr '\t' ' ' |
sed '
    /^#[0-9]/ s/^#//
    s/  *#.*//
    /^ *$/ d
' |
sort -k2 |
uniq -f 1 -c |
awk '$1 > 1 {print}'

上記のスクリプトの最後のステートメントはawkcountを使用して(field1)で行を検索します。uniq> 1

上記のスクリプトを実行すると、次のようになります。これ

答え2

もし実際データの先頭に説明するようなコメント行が存在し、無視されます。無視する重要なコメント行を区別する方法を想定せずに、ポイント2がどのように満足されるかわかりません。重要なコメント行の2番目のフィールドにピリオドが含まれているとします。

awk 'NF && $2 ~ /[.]/{++a[$2]}; 
 END{for (k in a) if(a[k] > 1) print k}' file
orange.domain.net
monkey.anotherdomain.net

答え3

sed 's/\(.\)#.*/\1/' file | cut -f 2 -d\ | sort | uniq -d
  • 前のコメントを削除sed 's/\(.\)#.*/\1/'
  • 2番目の列のみをフィルタリングcut -f 2 -d\
  • 次の比較のために行を並べ替えます。sort
  • そしてコピーだけを印刷してください。uniq -d

このような行を持つことができない場合は注意してください。

86.242.200.81 banana.domain.net#comment

上記の内容は次のように単純化できます。

cut -f 2 -d\  file | sort | uniq -d

コメントは3番目のフィールドとして扱われるからです。

答え4

短くてシンプルで直接的なアプローチはどうですか?

awk '/#*\d/{print $2}' file | sort | uniq -d

これにより、ホストドメインの重複がポンド記号(#)としてコメント化されている場合にも報告できます。

関連情報