我如何通过按bash中的大小(即非散列)进行比较来查找重复的文件

问题描述 投票:0回答:1

我如何通过按bash中的大小(即非散列)进行比较来查找重复的文件。

测试平台文件:

-rw-r--r--   1 usern  users  68239 May  3 12:29 The W.pdf
-rw-r--r--   1 usern  users  68239 May  3 12:29 W.pdf
-rw-r--r--   1 usern  users      8 May  3 13:43 X.pdf

是,文件可以有空格(嘘!)。

我想检查同一目录中的文件,将与其他文件匹配的文件移到“这些文件可能是重复的”文件夹中。

我可能的用例是,人类会随机地给一组较小的文件错误命名(即:不生成任意长度的文件)。两个文件大小相同而又是不同文件的可能性很小。当然,作为备份,我可以哈希并检查两个大小相同的文件。但是大多数情况下,这将是人们获取文件并将其命名错误/将其重新添加到已经存在的文件堆中。

因此,最好是具有广泛安装的工具的解决方案(posix?)。而且我不应该解析ls的输出,因此我需要另一种方法来获取实际大小(而不是du近似值)。

“投票结束!”

举起牛仔。

我敢打赌,你会建议这个(很酷,你可以用Google搜索):

https://unix.stackexchange.com/questions/71176/find-duplicate-files

没有fdupes(也没有jdupes,也没有...),也没有finddup,也没有rmlint,也没有fslint-我不能保证在其他系统上(我的更少)不想被客户支持卡住,从现在开始到永恒将它们安装在随机系统上,甚至不希望收到有关该东西的电子邮件,也不必告诉他们RTFM并加以解决。另外,实际上,我应该编写我的脚本来测试所安装内容的功能,但这超出了范围。

https://unix.stackexchange.com/questions/192701/how-to-remove-duplicate-files-using-bash

所有这些解决方案都希望从哈希开始。其中一些很酷的想法:仅散列两个文件的一部分,从头开始经过某个地方,然后仅在完全匹配时才进行完全比较。进行双重检查的好主意,但宁愿只对实际上很少重复的东西进行检查。因为,手动查看其中的前几千个,甚至没有一个副本接近另一个文件。https://unix.stackexchange.com/questions/277697/whats-the-quickest-way-to-find-duplicated-files

建议:

$ find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | sort | uniq -w32 --all-repeated=separate

对我来说很高兴:

find: unknown option -- n usage: find [-dHhLXx] [-f path] path ... [expression] uniq: unknown option -- w usage: uniq [-ci] [-d | -u] [-f fields] [-s chars] [input_file [output_file]] find: unknown option -- t usage: find [-dHhLXx] [-f path] path ... [expression] xargs: md5sum: No such file or directory

https://unix.stackexchange.com/questions/170693/compare-directory-trees-regarding-file-name-and-size-and-date

无法确定rsync -nrvc --delete如何在同一目录中工作,但其中可能有解决方案。

那么cmp好吗?是的,实际上看起来还不错!

cmp -z file1 file2

笨蛋,我的cmp版本不包含-z大小选项。

但是,我尝试仅针对咧嘴笑实现它-当它失败时,看着它,我意识到我还需要帮助构建循环逻辑。在处理它们的过程中从我的循环中删除它们可能是造成破坏的原因,嗯。

if [ ! -d ../Dupes/ ]; then mkdir ../Dupes/ || exit 1 # Cuz no set -e, and trap not working fi for i in ./* do for j in ./* do if [[ "$i" != "$j" ]]; then # Yes, it will be identical to itself if [[ $(cmp -s "$i" "$j") ]]; then echo "null" # Cuz I can't use negative of the comparison? else mv -i "$i" ../Dupes/ fi fi done done

https://unix.stackexchange.com/questions/367749/how-to-find-and-delete-duplicate-files-within-the-same-directory

可能有一些我可以使用的东西,但是我没有关注那里发生的事情。

https://superuser.com/questions/259148/bash-find-duplicate-files-mac-linux-compatible

如果是返回大小而不是md5的东西,也许是这里的答案之一?

https://unix.stackexchange.com/questions/570305/what-is-the-most-efficient-way-to-find-duplicate-files

没有真正得到答复。

TIL:从. scriptname发送错误将立即关闭我的终端。谢谢,谷歌!

[TIL:如果在配置文件中设置了shopt -s extdebug + trap checkcommand DEBUG以尝试捕获rm -r *,但是通过$ PATH执行的脚本发送错误将关闭终端,但至少会尊重我的exit别名

TIL:不推荐使用反引号,使用$(

things >>)-哎呀,这么多重写都可以做:P

TIL:如何在不使用basename的情况下捕获文件名中的非ASCII字符>

TIL:"${file##*/}"

TIL:file-是的,X.pdf不是PDF。

我如何通过在bash中按大小(即不进行散列)比较它们来查找重复文件。测试平台文件:-rw-r--r-- 1个用户用户68239 May 3 12:29 W.pdf -rw-r--r-- 1个用户用户68239 May 3 ...

< [

关于POSIX
我不确定是否可以在不使用ls的情况下获得纯文本格式的实际文件大小(而不是文件分配的块数)。所有解决方案,例如du --apparent-sizefind -printf %sstat都不是正数。但是,只要文件名不包含换行符(可以使用空格),就可以依靠ls创建安全的解决方案。无论如何,正确地使用换行符处理文件名将需要非常非posix的工具(如GNU sort -z)。

但是,即使使用posix,即使只列出当前目录中的文件也是一个巨大的痛苦。 find -maxdepth也不是posix。因此,此解决方案将不严格符合posix。但是,我尝试验证大多数解决方案都支持此解决方案中的工具和选项。

方法

我建议

不使用嵌套循环。 bash中的循环已经很慢了,但是如果嵌套它们,则将具有二次时间复杂度。更快,更轻松地

仅打印不带文件名的文件大小

    应用sort | uniq -d在时间O(n log n)中检索重复项

  • 将具有重复大小之一的所有文件移动到目录中为此,我们创建一个find
  • #! /bin/bash all=$(find . -maxdepth 1 -type f -printf '%s %p\n' | sort) dupRegex=$(cut -d' ' -f1 <<< "$all" | uniq -d | sed 's/^/^/' | tr \\n \| | sed 's/|$//') [ -z "$dupRegex" ] && exit mkdir -p potential-dups grep "$dupRegex" <<< "$all" | cut -d' ' -f2- | sed 's/./\\&/' | xargs -I_ mv _ potential-dups

  • bash scripting duplicates size
    1个回答
    0
    投票
    © www.soinside.com 2019 - 2024. All rights reserved.