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 校验和列表。*.jpg
find
*.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.