如何为新文件创建 md5sum
How to create md5sum for new files
我们在我爸爸的电脑上创建了一个文件夹,供全家人存放和分享他们的照片和视频。
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
我将使用 ls -l(并将其存储在临时文件中),
然后在 Daily 上用一个新的 ls 来区分它?基础,如果 diff returns 0 一切都很好,如果 diff 显示差异。
然后我将仅 md5 由 diff 报告的文件,用新的 ls 更新 ls 临时文件。我将使用 --LTYPE-line-format=%<
这样它就不会查找已删除的文件(文件存在于临时文件中但不存在于 fresh-运行 ls 中)。
这将是查找 'new' 个文件的前提代码:
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
我离开去写其他代码(首先制作临时文件并对数据进行哈希处理)
显然,如果您有一个目录,您必须 运行 ls -R
而不是 运行 您要检查的路径根目录中的脚本
解决方案
这应该可以解决问题:
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
, 因为 md5deep
似乎将这样的路径写入文件,我们需要它们相同才能进行比较。
- 此命令行使用 bash 特定语法(将命令作为文件传递),可能无法在不同的 shell 解释器中工作。
说明
comm -1 -3
- 在这种特定情况下,我们使用此命令通过将找到的文件与现有列表进行比较来查看哪些文件是新文件。
comm
比较两个排序列表并输出哪些行对每个列表是唯一的,哪些行对两个列表都是相同的
-1
表示:不显示第一个列表独有的行
-3
表示:不显示两个文件共有的行[=115=]
- 因此我们只输出第二个列表特有的行
<(grep --text --perl-regex --only-matching '(?<= ).+' /Family_Photo/md5sum.log | sort)
作为 comm
的第一个文件,我们传递了一个已经散列的文件名列表。
<(...)
是 bash 将程序结果作为文件参数传递的语法
- 使用
grep
,我们通过匹配double-space 后的任何内容从现有文件中提取文件名
--text
确保 md5sum.log 始终被视为文本文件而不被跳过
--perl-regex
使用 perl 正则表达式语法(我们需要它进行后视匹配)
--only-matching
只输出与模式匹配的文本,而不是匹配的整行
'(?<= ).+'
匹配模式:(?<= )
"look-behind" 模式,检查匹配前面是否有 </code> (两个 spaces );后跟 <code>.+
(任意字符,一个或多个)
| sort
我们将 grep
的输出传递给 sort
,因为 comm
需要排序列表
<(find /Family_Photo -type f | sort)
作为 comm
的第二个文件,我们传递找到的所有文件
<(...)
是 bash 将程序结果作为文件传递的语法
find
将递归给定目录并打印出所有文件名
-type -f
指示 find 只输出找到的文件名,不输出目录
| sort
我们将 grep
的输出传递给 sort
,因为 comm
需要排序列表
| xargs --delimiter='\n' --no-run-if-empty md5deep
生成的新文件列表传递给 md5deep
|
将 comm
的输出连接到 xargs
的输入
xargs
将调用命令(在本例中为 md5deep
),将输入的任何内容作为参数
--delimiter='\n'
指定一个新行作为分隔符,这样文件名中的其他白色space就不会被误认为是新参数
--no-run-if-empty
如果我们没有要传递给它的新文件名,我们不想 运行 md5deep
。
| tee --append /Family_Photo/md5sum.log
生成的列表哈希将写入哈希文件
- 这会显示新的 files/hashes 以方便您编写它们,如果您不想看到它们,只需使用
>> /Family_Photo/md5sum.log
即可。
|
将 md5deep
的输出连接到 tee
的输入
tee
将输出其输入并将其写入文件
--append
告诉 tee
不要覆盖文件内容,而是附加
感谢大家的投入。经过一番折腾,我想出了一些满足我当前需求的东西。
这部分是运行第一次
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
我们在我爸爸的电脑上创建了一个文件夹,供全家人存放和分享他们的照片和视频。
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
我将使用 ls -l(并将其存储在临时文件中),
然后在 Daily 上用一个新的 ls 来区分它?基础,如果 diff returns 0 一切都很好,如果 diff 显示差异。
然后我将仅 md5 由 diff 报告的文件,用新的 ls 更新 ls 临时文件。我将使用 --LTYPE-line-format=%<
这样它就不会查找已删除的文件(文件存在于临时文件中但不存在于 fresh-运行 ls 中)。
这将是查找 'new' 个文件的前提代码:
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
我离开去写其他代码(首先制作临时文件并对数据进行哈希处理)
显然,如果您有一个目录,您必须 运行 ls -R
而不是 运行 您要检查的路径根目录中的脚本
解决方案
这应该可以解决问题:
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
, 因为md5deep
似乎将这样的路径写入文件,我们需要它们相同才能进行比较。 - 此命令行使用 bash 特定语法(将命令作为文件传递),可能无法在不同的 shell 解释器中工作。
说明
comm -1 -3
- 在这种特定情况下,我们使用此命令通过将找到的文件与现有列表进行比较来查看哪些文件是新文件。
comm
比较两个排序列表并输出哪些行对每个列表是唯一的,哪些行对两个列表都是相同的-1
表示:不显示第一个列表独有的行-3
表示:不显示两个文件共有的行[=115=]- 因此我们只输出第二个列表特有的行
<(grep --text --perl-regex --only-matching '(?<= ).+' /Family_Photo/md5sum.log | sort)
作为comm
的第一个文件,我们传递了一个已经散列的文件名列表。<(...)
是 bash 将程序结果作为文件参数传递的语法- 使用
grep
,我们通过匹配double-space 后的任何内容从现有文件中提取文件名
--text
确保 md5sum.log 始终被视为文本文件而不被跳过--perl-regex
使用 perl 正则表达式语法(我们需要它进行后视匹配)--only-matching
只输出与模式匹配的文本,而不是匹配的整行'(?<= ).+'
匹配模式:(?<= )
"look-behind" 模式,检查匹配前面是否有</code> (两个 spaces );后跟 <code>.+
(任意字符,一个或多个)| sort
我们将grep
的输出传递给sort
,因为comm
需要排序列表
<(find /Family_Photo -type f | sort)
作为comm
的第二个文件,我们传递找到的所有文件<(...)
是 bash 将程序结果作为文件传递的语法find
将递归给定目录并打印出所有文件名-type -f
指示 find 只输出找到的文件名,不输出目录| sort
我们将grep
的输出传递给sort
,因为comm
需要排序列表
| xargs --delimiter='\n' --no-run-if-empty md5deep
生成的新文件列表传递给 md5deep|
将comm
的输出连接到xargs
的输入
xargs
将调用命令(在本例中为md5deep
),将输入的任何内容作为参数--delimiter='\n'
指定一个新行作为分隔符,这样文件名中的其他白色space就不会被误认为是新参数--no-run-if-empty
如果我们没有要传递给它的新文件名,我们不想 运行md5deep
。
| tee --append /Family_Photo/md5sum.log
生成的列表哈希将写入哈希文件- 这会显示新的 files/hashes 以方便您编写它们,如果您不想看到它们,只需使用
>> /Family_Photo/md5sum.log
即可。 |
将md5deep
的输出连接到tee
的输入
tee
将输出其输入并将其写入文件--append
告诉tee
不要覆盖文件内容,而是附加
- 这会显示新的 files/hashes 以方便您编写它们,如果您不想看到它们,只需使用
感谢大家的投入。经过一番折腾,我想出了一些满足我当前需求的东西。
这部分是运行第一次
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