检查一个文件夹中的所有文件是否也在另一个文件夹中

检查一个文件夹中的所有文件是否也在另一个文件夹中

a我基本上有一个包含大量图像的目录。现在我想检查所有这些图像是否都在目录中b。关键是,很多图像b不是直接在子目录中b而是在子目录中。

另外,我不想依赖文件名,而是依赖文件内容。

(因为 bash 标签:我更喜欢 bash 答案,但如果是其他语言或者使用其他程序,也可以)

答案1

由于您想按内容比较它们,因此使用哈希似乎是一种方法。

您可以使用该find命令获取目录的文件路径列表。该-type f选项将忽略所有目录,仅输出常规文件的路径。该-exec md5sum {} \;选项将获取找到的路径并将它们提供给命令md5sum以转换为列表 md5 哈希 + 它们的文件路径('md5_hash /path/to/file')。

我们将该列表通过管道传输到cut命令中。第一个选项-f 1告诉它仅采用第一列(哈希值)。第二个-d ' '告诉它使用空格字符作为列之间的分隔符。默认为 TAB。

我们将该哈希列表通过管道传输到排序命令中,以使其更容易diff

操作<( command )员称为流程替代。它获取命令的输出并将其转换为需要它们作为输入的命令的伪文件(有关不太简单的解释,请点击链接)。这样,看起来diff就像我们想要比较两个文件一样。

:~$ diff <(find folder1/ -type f -exec md5sum {} \; | cut -f 1 -d ' ' | sort) \
    <(find folder2/ -type f -exec md5sum {} \; | cut -f 1 -d ' ' | sort)

注意:不要忘记将folder1/ 和folder2/ 替换为您的实际文件夹。

这将为您提供仅在其中一个中的文件的 md5 哈希值列表。

如果您想知道哪些文件实际上丢失了,您可以执行以下操作:

:~$ find folder1/ -type f -exec md5sum {} \; | sort | grep my_md5_hash

如果您有很多文件要检查,明智的做法是保存两个<(find ...)命令的结果并进行比较,如下所示:

:~$ diff list1.txt list2.txt
:~$ cat list1.txt | grep my_md5_hash

答案2

查看答案对于类似的问题从两周前开始。

find . -type f -exec md5sum {} + | sort | sed 's/  */!/1' | awk -F\| 'BEGIN{first=1}{if($1==lastid){if(first){first=0;print lastid, lastfile}print$1, $2} else first=1; lastid=$1;lastfile=$2}'

答案3

假设这些都是 *.jpg 文件,请执行以下操作:

要查找存在的文件:

grep -Ff <(for i in </path/to/directory/a>/*.jpg ; do md5sum $i | awk {'print $1'}; done) <(find </path/to/directoryb/ -iname "*.jpg" | xargs md5sum)

这里的循环创建目录“a”中for所有文件的 md5 校验和列表,这里将创建目录“b”(包括 sudirectories)中所有文件的 md5 校验和列表。*.jpgfind*.jpg

grep -fF比较这两个列表,完整的命令将生成 2 列输出,第一列是存在的文件的 md5 校验和,第二列是目录 ' 中匹配的文件的文件名(带有完整路径) b'。| awk {'print $2'}如果您只想获取文件名,则可以使用附加项。

要查找不存在的文件:

grep -vFf <(for i in </path/to/directory/a>/*.jpg ; do md5sum $i | awk {'print $1'}; done) <(find </path/to/directoryb/ -iname "*.jpg" | xargs md5sum

与第一个 grep 命令执行相同的操作,但使用该-v选项仅列出不匹配的内容。

您正在寻找什么:

如果目录“a”中的所有文件都存在,则第二个 grep 不应返回任何输出。

将 *.jpg 替换为您可能希望搜索的任何扩展名。

man页面grep

   -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.
          (-f is specified by POSIX.)

    -F, --fixed-strings
          Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to  be  matched.   (-F  is
          specified by POSIX.)

-v, --invert-match
              Invert the sense of matching, to select non-matching lines. 

相关内容