md5目录树中的所有文件

时间:2016-04-28 16:21:45

标签: bash for-loop find md5 directory-structure

我有一个像这样结构的目录:

.
├── Test.txt
├── Test1
│   ├── Test1.txt
│   ├── Test1_copy.txt
│   └── Test1a
│       ├── Test1a.txt
│       └── Test1a_copy.txt
└── Test2
   ├── Test2.txt
   ├── Test2_copy.txt
   └── Test2a
       ├── Test2a.txt
       └── Test2a_copy.txt

我想创建一个bash脚本,对该目录中的每个文件进行md5校验和。我希望能够在CLI中键入脚本名称,然后输入我想要哈希的目录的路径并让它工作。我确信有很多方法可以实现这一目标。目前我有:

#!/bin/bash

for file in "$1" ; do 
    md5 >> "${1}__checksums.md5"
done

这只是挂起而且无法正常工作。也许我应该使用find?

一个警告 - 我想要哈希的目录将包含具有不同扩展名的文件,并且可能并不总是具有完全相同的树结构。我想要一些能在这些不同情况下起作用的东西。

6 个答案:

答案 0 :(得分:23)

使用$ java -jar bin/pdfboxer-0.0.1.jar \ -trimBox 7.200000,7.200000,504.000031,720.000000 \ -artBox 7.200000,7.200000,504.000031,720.000000 \ -sourceFile src/test/pdfs/UNTRIMMED_PDF.pdf \ -destFile src/test/pdfs/TRIMMED_PDF.pdf

md5deep

使用md5deep -r path/to/dir > sums.md5 find

md5sum

请注意,当您使用find relative/path/to/dir -type f -exec md5sum {} + > sums.md5 检查MD5总和时,需要从生成md5sum -c sums.md5文件的同一目录运行它。这是因为sums.md5输出了相对于当前位置的路径,然后将这些路径放入find文件中。

如果这是一个问题,您可以sums.md5绝对(例如,将relative/path/to/dir放在您的路径前)。这样您就可以从任何位置对$PWD/进行检查。缺点是,现在sums.md5包含绝对路径,这使得它更大。

使用sums.md5find

的全功能功能

您可以将此功能添加到md5sum文件(位于.bashrc目录中):

$HOME

运行function md5sums { if [ "$#" -lt 1 ]; then echo -e "At least one parameter is expected\n" \ "Usage: md5sums [OPTIONS] dir" else local OUTPUT="checksums.md5" local CHECK=false local MD5SUM_OPTIONS="" while [[ $# > 1 ]]; do local key="$1" case $key in -c|--check) CHECK=true ;; -o|--output) OUTPUT=$2 shift ;; *) MD5SUM_OPTIONS="$MD5SUM_OPTIONS $1" ;; esac shift done local DIR=$1 if [ -d "$DIR" ]; then # if $DIR directory exists cd $DIR # change to $DIR directory if [ "$CHECK" = true ]; then # if -c or --check option specified md5sum --check $MD5SUM_OPTIONS $OUTPUT # check MD5 sums in $OUTPUT file else # else find . -type f ! -name "$OUTPUT" -exec md5sum $MD5SUM_OPTIONS {} + > $OUTPUT # Calculate MD5 sums for files in current directory and subdirectories excluding $OUTPUT file and save result in $OUTPUT file fi cd - > /dev/null # change to previous directory else cd $DIR # if $DIR doesn't exists, change to it to generate localized error message fi fi } 后,您可以像正常命令一样使用source ~/.bashrc

md5sums

将在md5sums path/to/dir 目录中生成checksums.md5文件,其中包含此目录和子目录中所有文件的MD5总和。使用:

path/to/dir

检查md5sums -c path/to/dir 文件的总和。

请注意path/to/dir/checksums.md5可以是相对的或绝对的,path/to/dir无论如何都可以正常工作。生成的md5sums文件始终包含相对于checksums.md5的路径。 您可以通过提供path/to/dirchecksums.md5选项使用不同的文件名,然后使用默认-o。除--output-c--check-o之外的所有选项都会传递给--output

md5sum函数定义的前半部分负责解析选项。有关它的更多信息,请参阅this answer。下半部分包含解释性意见。

答案 1 :(得分:4)

怎么样:

find /path/you/need -type f -exec md5sum {} \; > checksums.md5

更新#1:根据@ twalberg的建议改进了命令,以处理文件名中的空格。

更新#2 :根据@ jil的建议进行了改进,删除了不必要的xargs电话,并改为使用-exec选项。

更新#3: @Blake您的脚本的简单实现看起来像这样:

#!/bin/bash
# Usage: checksumchecker.sh <path>
find "$1" -type f -exec md5sum {} \; > "$1"__checksums.md5

答案 2 :(得分:1)

#!/bin/bash
shopt -s globstar
md5sum "$1"/** > "${1}__checksums.md5"

说明:shopt -s globstar (manual)启用**递归glob通配符。这意味着"$1"/**将在作为参数$1给出的目录下递归地扩展到所有文件的列表。然后,脚本只需使用此文件列表作为参数调用md5sum> "${1}__checksums.md5"将输出重定向到文件。

答案 3 :(得分:1)

更新了答案

如果您喜欢下面的答案或其他任何答案,您可以创建一个为您执行命令的功能。因此,要测试它,请在Terminal中键入以下内容以声明一个函数:

function sumthem(){ find "$1" -type f -print0 | parallel -0 -X md5 > checksums.md5; }

然后你可以使用:

sumthem /Users/somebody/somewhere

如果您喜欢这种方式,可以将该行添加到&#34; bash配置文件&#34; 的末尾,只要您登录,该功能就会被声明并可用。您的&#34; bash个人资料&#34; 可能在$HOME/.profile

原始答案

为什么不让所有CPU内核并行工作?

find . -type f -print0 | parallel -0 -X md5sum

这将查找当前目录(-type f)中的所有文件(.),并在结尾处使用空字节打印它们。然后将这些传递给 GNU Parallel ,告知文件名以空字节(-0)结尾,并且它应该一次执行尽可能多的文件({{ 1}})保存为每个文件创建一个新进程,它应该md5sum文件。

这种方法将在速度方面支付最大的奖励,包括像Photoshop文件这样的大图像。

答案 4 :(得分:1)

md5deep -r $your_directory | awk {'print $1'} | sort | md5sum | awk {'print $1'}

答案 5 :(得分:0)

使用查找命令列出目录树中的所有文件, 然后使用 xargs md5sum 命令提供输入

find dirname -type f | xargs md5sum > checksums.md5