我有一个文本文件,其中的行是这样混合的:
### 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
如何找到重复的host.domain?
在这种情况下,有两个: monkey.anotherdomain.net
和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
如果我们对第二列 ( 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}'
上述脚本中的最后一条语句查找(field1)awk
中的计数为 的行。uniq
> 1
运行上面的脚本看起来像这。
答案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/'
- 仅过滤第二列
cut -f 2 -d\
- 对行进行排序以便进行以下比较
sort
- 并且只打印副本
uniq -d
请注意,除非有可能有像这样的行
86.242.200.81 banana.domain.net#comment
您可以将上面的内容简化为:
cut -f 2 -d\ file | sort | uniq -d
因为评论将被视为第三个字段。
答案4
那么短、简单、直的方法怎么样呢?
awk '/#*\d/{print $2}' file | sort | uniq -d
这允许报告 host.domain 重复项,即使它们被井号 (#) 注释掉。