对每个子目录中的文件进行 MD5 计算,给定一个起始目录,将校验和文件放在子目录中

对每个子目录中的文件进行 MD5 计算,给定一个起始目录,将校验和文件放在子目录中

在运行该命令之前,我需要为该命令提供哪些标志才能find进入目录-exec

我有一个目录,里面充满了文件和目录

> root directory
 -> directory1
  -> file1
  -> file2...
 -> directory2
  ->file1
  ->file2
 -> directory...

我想在每个目录中放置一个校验和文件,其中包含目录内容的总和:

> root directory
 -> directory1
  -> file1
  -> file2...
  -> checksums.md5
 -> directory2
  ->file1
  ->file2
  -> checksums.md5
 -> directory...

我一直在摆弄

find . -type f -name '*' -exec md5sum {} >> checksums.md5 \;

但它将校验和文件放在根目录(起点),另外该文件还包含全部文件。我尝试使用该-execdir标志,但无济于事。

我想要做的是对每个文件夹的内容进行 MD5 运算并将校验和文件放在其中,然后转到下一个文件夹并重复。

最好也对 checksums.md5 文件的内容进行排序。

答案1

您需要执行附加操作每个文件

find ... -execdir bash -c 'md5sum "{}" >> checksum.md5' \;

答案2

我只是找不到合适的标志来添加到 find 命令中。因此,我使用了循环,我认为肯定存在比这更好的解决方案,即使只使用find

遍历每个目录

因此,在你编写的命令中,文件checksum.md5是在当前目录(对您来说,这是 root 权限)。为了在每个子目录中创建校验和文件,您必须遍历该目录,执行命令,然后返回当前目录。不完全是,但类似于以下内容:

cd directory1; md5sum * >> checksum.md5 ; cd ..;

使用循环中的 find

因此,我仅使用了您使用过的几行代码,并将其放入一个循环中,该循环遍历当前目录中存在的所有子目录。以下是我所做的:

for i in $( ls -d */ );
  do cd $i && find . -type f -name '*' -exec md5sum {} >> checksum_files.md5 \; && cd ..;
  done; 

它的作用是:

  • $i包含循环迭代的目录列表。
  • cd $i将当前目录更改为列表中的某个子目录。
  • 然后是find你已经写好的命令。
  • cd ..遍历回到当前目录(本例中为根目录)。
  • 我使用和&&之间来明确设置条件,即如果它进入子目录,则仅执行查找命令。cdfind

一行即可复制粘贴

for i in $( ls -d */ ); do cd $i && find . -type f -name '*' -exec md5sum {} >> checksum_files.md5 \; && cd ..; done; 

我认为这个解决方案还有改进的空间,欢迎大家提出任何改进建议。欢迎添加更多细节。

答案3

为了构建 Ignacio Vazquez-Abrams 的答案,我制作了以下 bash 函数,该函数抓取子目录并对其内容进行 MD5 处理,将 MD5 文件放在子目录中,然后对校验和文件进行后期处理以对其进行排序,以便生成的校验和根据文件名按顺序排列:

function md5dirs () {
  find . -type f -name '*' -execdir bash -c 'md5sum "{}" >> checksums.md5' \;
  find . -type f -name 'checksums.md5' -execdir bash -c 'sort -k 2 "{}" -o checksums.md5' \;
}

更改第一个 find 的-name参数以包含通配符扩展名,例如*.jpg将使 find 命令仅对目录中的 MD5 特定文件进行哈希处理。默认情况下,*它会对目录中的所有文件进行哈希处理。

也许对于某些人来说,将第一个 find 的-name参数设为传递值会更好,但大多数人会对文件夹的全部内容进行散列,而不仅仅是文件的子集。

相关内容