必须有一种“简单”的方法来做到这一点,但我不知道它是什么。
假设您有一个纯文本“file.txt”,其中包含以下格式的行(md5 和后跟文件名):
5ee434a2ebcf4c3c98ee07e9c1efddc0 foo.txt
365a6d8b18cab348d92db610dfc46264 bar.txt
ae42d992bf622bdc425d37b04ec9c2d5 mini.txt
b8e9ff5502d5dbe38b3fd5e3363caacf tyrion.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 imac.txt
542ed609dfc4d0cae44c4b7be6d66382 mba.txt
310ee92ebc69ed79c1837fc53983b7f8 mini luoma.txt
542ed609dfc4d0cae44c4b7be6d66382 tyrion final.txt
我想排序file.txt
并输出:
- 仅当 md5 总和指示文件重复时才显示行
- 在每个“组”重复项之间放置一个空行。
所以它看起来像这样:
542ed609dfc4d0cae44c4b7be6d66382 mba.txt
542ed609dfc4d0cae44c4b7be6d66382 tyrion final.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 foo.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 imac.txt
(在实际情况中,可能有 2 个重复项,也可能有 10 个或更多。)
我猜可能会有一位ruby
或python
一位大师能够解决这个问题,但我对几乎任何实际的解决方案持开放态度。
答案1
$ sort file.txt \
| grep -f <(cut -d' ' -f1 file.txt | sort | uniq -d) \
| awk 'last && last != $1 { printf "\n" }; { last=$1 ; print}'
542ed609dfc4d0cae44c4b7be6d66382 mba.txt
542ed609dfc4d0cae44c4b7be6d66382 tyrion final.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 foo.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 imac.txt
(感谢“cas”的 awk 建议。)
(感谢“steeldriver”注意到一个错误。)
答案2
与sort
和uniq
sort file.txt | uniq -w 32 --all-repeated=separate
542ed609dfc4d0cae44c4b7be6d66382 mba.txt
542ed609dfc4d0cae44c4b7be6d66382 tyrion final.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 foo.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 imac.txt
-w 32
限制uniq
与 MD5 散列的比较(因此它认为具有相同 MD5 的等于行)--all-repeated=separate
告诉它显示重复项,同时用空行分隔组
答案3
使用 perl 数组哈希:
$ perl -alne '
push @{ $h{$F[0]} }, $_
}{
for $k (sort keys %h) {
@a = @{ $h{$k} };
print join "\n", @a, "" if $#a > 0
}
' file.txt
542ed609dfc4d0cae44c4b7be6d66382 mba.txt
542ed609dfc4d0cae44c4b7be6d66382 tyrion final.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 foo.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 imac.txt
请注意,这会在最后一条记录之后打印一个尾随空白行。是sort
可选的。
GNU awk 中类似的事情:
gawk '
{a[$1][NR] = $0}
END {
for(k in a){
if(length(a[k]) > 1) {
for(v in a[k]) print a[k][v];
print "";
}
}
}
' file.txt