给定文件列表,有些重复,有些不重复,仅显示重复项的校验和

给定文件列表,有些重复,有些不重复,仅显示重复项的校验和

必须有一种“简单”的方法来做到这一点,但我不知道它是什么。

假设您有一个纯文本“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并输出:

  1. 仅当 md5 总和指示文件重复时才显示行
  2. 在每个“组”重复项之间放置一个空行。

所以它看起来像这样:

542ed609dfc4d0cae44c4b7be6d66382 mba.txt
542ed609dfc4d0cae44c4b7be6d66382 tyrion final.txt

5ee434a2ebcf4c3c98ee07e9c1efddc0 foo.txt
5ee434a2ebcf4c3c98ee07e9c1efddc0 imac.txt

(在实际情况中,可能有 2 个重复项,也可能有 10 个或更多。)

我猜可能会有一位rubypython一位大师能够解决这个问题,但我对几乎任何实际的解决方案持开放态度。

答案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

sortuniq

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

相关内容