如何为新文件创建md5sum

时间:2018-06-03 09:50:57

标签: bash md5sum

我们在爸爸的电脑上创建了一个文件夹,供家里的每个人存放和分享他们的照片和视频。

Example of directories:
/Family_Photo/Penguins/2017 09 02/
/Family_Photo/East Beach/2017 10 11/Seaside/
/Family_Photo/East Beach/2017 10 11/Games/

使用md5deep,我可以为所有子目录中的所有文件创建一个完整的校验和列表

md5deep -r /Family_Photo/ > /Family_Photo/md5sum.log

而不是每次为所有(新添加的和现有的)文件重新生成完整的md5校验和,

如何创建一个bash脚本来自动检测之前没有md5的文件,并为这些新文件生成校验和,并将它们附加到原始的md5sum.log

3 个答案:

答案 0 :(得分:1)

谢谢大家的投入。经过艰苦的努力,我提出了一些可以满足我当前需求的东西。

这部分是第一次运行

md5deep -r /Family_Photos/ > /Family_Photo/photos.md5
cd Family_Photos/ & find . -print | sort > today.txt

下一部分将构成我的脚本。 为每次运行准备txt文件。

cd Family_Photos/ & rm old.txt & mv today.txt old.txt

要将所有文件递归列出到today.txt中

find . -print | sort > today.txt

将新添加的文件更新为new.txt

grep -xvFf old.txt today.txt > new.txt

生成所有新文件的md5sum,并将其追加到photos.md5

cat new.txt | xargs -d '\n' md5sum >> photos.md5

答案 1 :(得分:0)

<强>解决方案

这应该可以解决问题:

comm -1 -3 <(grep --text --perl-regex --only-matching '(?<= ).+' /Family_Photo/md5sum.log | sort) <(find /Family_Photo -type f | sort) | xargs --delimiter='\n' --no-run-if-empty md5deep | tee -a /Family_Photo/md5sum.log

备注

  • 如果您使用的路径与示例中的路径不同,请确保使用绝对和规范路径-exec realpath {} \;选项附加到find,因为{ {1}}似乎将这些路径写入文件中,我们需要它们相同才能进行比较。
  • 此命令行使用 bash 特定语法(将命令作为文件传递),并且可能无法在不同的shell解释器中使用。

<强>解释

  • md5deep
    • 我们在此特定情况下使用此命令,通过将找到的文件与现有列表进行比较来查看哪些文件是新文件。
    • comm -1 -3比较两个排序列表,并输出哪些行对于每个行都是唯一的,哪些行对于两者都是通用的
    • comm表示:不显示第一个列表唯一的行
    • -1表示:不显示两个文件共有的行
    • 因此我们只输出第二个列表唯一的行
  • -3作为<(grep --text --perl-regex --only-matching '(?<= ).+' /Family_Photo/md5sum.log | sort)的第一个文件,我们传递已经散列过的文件名列表。
    • comm是用于将程序结果作为文件参数传递的bash语法
    • 使用<(...),我们通过匹配双空格
    • 之后的内容从现有文件中提取文件名
    • grep确保md5sum.log始终被视为文本文件而不会被跳过
    • --text使用perl正则表达式语法(我们需要这个用于后台匹配)
    • --perl-regex仅输出与模式匹配的文字,而不是匹配
    • 的整行
    • --only-matching匹配模式:'(?<= ).+'“look-behind”模式,检查匹配是否前面有(?<= )(两个空格);然后是(任何字符,一个或多个)
    • .+我们将| sort的输出传递给grep,因为sort需要排序列表
  • comm作为<(find /Family_Photo -type f | sort)的第二个文件,我们会传递我们找到的所有文件
    • comm是用于将程序结果作为文件
    • 传递的bash语法
    • <(...)将递归给定目录并打印出所有文件名
    • find指示find仅输出找到的文件的名称,而不是目录
    • -type -f我们将| sort的输出传递给grep,因为sort需要排序列表
  • comm生成的新文件列表将传递给md5deep
    • | xargs --delimiter='\n' --no-run-if-empty md5deep|的输出与comm
    • 的输入相关联
    • xargs将调用命令(在本例中为xargs),其中包含任何作为参数的输入
    • md5deep指定一个新行作为分隔符,以便文件名中的其他空格不会被误认为是新参数
    • --delimiter='\n'如果我们没有一个新的文件名传递给它,我们不想运行--no-run-if-empty
  • md5deep生成的列表哈希值将写入哈希文件
    • 为了方便起见,会显示新文件/哈希值,如果您不想看到它们,请改用| tee --append /Family_Photo/md5sum.log
    • >> /Family_Photo/md5sum.log|的输出与md5deep
    • 的输入相关联
    • tee将输出其输入并将其写入文件
    • tee告诉--append不要覆盖文件内容,而是要附加

答案 2 :(得分:-1)

我将采用ls -l(并将其存储在临时文件中),
然后在每日的新ls上区分?基础,如果diff返回0,则一切正常,如果差异显示差异 然后我只使用diff报告的文件,用新的ls更新ls tempfile。我将使用--LTYPE-line-format=%<,因此它不会查找已删除的文件(文件中存在的文件,但不包含在新运行的文件中)。

这将是寻找新的&#39;的presudo-code。文件:

new_files=diff --suppress-common-lines --changed-group-format='%<' --unchanged-group-format='' temp_file $(ls -l)

deleted_files=diff --suppress-common-lines --changed-group-format='%>' --unchanged-group-format='' temp_file $(ls -l) #so you can log deletions too

我留下来编写其他代码(make first tempfile和hash the data)

显然,如果您有一个目录,则必须运行ls -R,而不是从要保持检查的路径的根目录运行脚本