给定一个我知道已复制到给定目录中的文件,我想找到文件副本现在所在的确切路径。保证该文件未经编辑,并且看起来与副本完全相同。
没有必要检查整个目录及其所有子目录,因为我知道有关文件可能所在位置的一些信息。这些文件有两个特征:RUN 和 VERSION,这是我们已知的,可以缩小文件副本可能所在的位置。
该解决方案可能会用于diff
比较文件,或者grep
选择find
我真正想要查看的目录。然而,我不知道如何将它们组合在一起。
因此,我们有一个文件 ( MYFILE=data.txt
),并且想知道其副本的路径(例如Jun-09/15/version3/run1
),并且我们已经知道,例如,一些可以避免的目录。例如,对于某些给定的文件,我们可能知道RUN=run1
,在这种情况下,我们不应该查看“run2”目录。同样,我们可能知道VERSION=version3
,在这种情况下我们不应该查看 version1 或 version2 目录。值得注意的是,该文件也可能没有副本,在这种情况下我也想知道。
文件结构的说明:相关目录对于过去 7 年的每个月都有一个文件夹(例如,称为“Jun-09”),并且每个子目录对于每一天都有一个文件夹(例如,“11”代表第 11 天)当月)。然后,每个“日”文件夹都有一个对应每个“版本”的文件夹(相关数据有 3 个“版本”),并且每个文件夹都有两个“运行”。然而,尽管文件夹是按时间组织文件的,但不能保证文件是在当月创建或最后编辑的。
我的尝试:我尝试从上述结构的根目录运行,find . -type f -name data.txt | diff ~/myOtherdirectory/files/data.txt
但我不断收到“‘~/myOtherdirectory/files/data.txt’后缺少操作数”。理想情况下,这样做是找到我正在查看的文件和它可能存在的所有其他文件之间的差异。它根本不会缩小要查看的目录范围,并且实际上不会获取副本的路径。
答案1
我建议你——取决于你的软件——fslint、duff、fdupes、dmerge、rmlint、rdfind——它们都能够比 fdupes 或 dupseek 更快地找到双胞胎。
我会执行:
$ find /path -type f -printf "%p - %s\n" | sort -nr -k3 | uniq -D -f1
答案2
myfile=/full/path/to/data.txt
mysearchpath=/my/search/path/root/directory
for file in $(find ${mysearchpath} -type f)
do
diff ${myfile} ${file} > /dev/null
result=${?}
if [ $result -eq 0 ]
then
echo "Identical file found at ${file}"
fi
done
尽管这是一种非常昂贵的方法(在计算资源方面,特别是当您与其他人共享此服务器做其他事情时)。您可以创建这些文件的校验和,并且可以运行一个作业来创建在任何给定日期添加的文件的校验和,并将它们放在某个平面文件中。当您需要查找文件时,创建该文件的校验和并将其与校验和数据库进行比较。只是一些值得深思的东西。
答案3
如果这是需要定期检查的内容,您可以设置一个 cron 作业来创建文件的 md5 哈希值的摘要,例如
echo > $digest_file; find $search_path -type f | xargs md5sum >> $digest_file
假设自从您的文件被复制后就已经运行了此操作,请首先找到已知文件的哈希值,然后检查列表中是否有具有相同哈希值的其他文件。当然,性能取决于搜索路径中文件的数量和大小。
这样做的另一个好处是,如果您在每次运行之前复制摘要并比较新旧摘要,则可以检测数据损坏/更改。
答案4
与find
和cmp
:
find . -type f -exec sh -c 'cmp -s data.txt "$0" 2>/dev/null && echo $0' {} \;
您可能想要添加更多条件来限制查找。