2015 年 1 月,我将一些文件从 dd 创建的备份映像传输到新硬盘。此传输未保留时间戳,因此基本上每个文件都显示 1 月 20 日的时间戳。
从那时起,许多文件已经被修改,新的文件已经被创建等等,但是更多的文件仍然与 dd 图像上的副本相同(时间戳除外)。
我想以递归方式将 dd 映像文件中的时间戳复制到新磁盘上的匹配文件中,但前提是文件相同(即,前提是文件自原始副本以来没有被修改过)。
我尝试过 rsync、touch 等各种方法,但还是没能搞定。我认为类似下面的伪代码可以工作,但我对 bash 脚本非常不熟悉。
for each file_in_dd_image
if (md5sum(file_in_dd_image) == md5sum(file_on_harddisk))
touch file_on_harddisk --reference=file_in_dd_image
或者,也许更好,因为如果文件在传输后被移动它也会起作用,有没有什么方法可以处理输出jdupes -rO dd_image harddisk
?
任何帮助将不胜感激!
答案1
我有非常类似的需求,所以这是我的解决方案。
Bash 脚本可能有点棘手,特别是涉及带有空格的文件名时,如果您做错了,最终可能会造成严重破坏,因此最好将其分成可管理、可测试的部分。
第 1 部分,仅对一个文件执行所需行为的脚本:
#!/bin/bash
# Usage: copy_timestamp_if_identical.sh source_file dest_file
test "$#" -eq 2 || { echo "Wrong number of arguments" >&2; exit 1; }
FILE1="$1"
FILE2="$2"
test -f "$FILE1" || { echo "File \"$FILE1\" not found" >&2; exit 1; }
test -f "$FILE2" || { echo "File \"$FILE2\" not found" >&2; exit 1; }
if test "$(basename "$FILE1")" != "$(basename "$FILE2")";
then
# Not same filename
exit;
fi
if test $(md5sum "$FILE1" | cut -d ' ' -f 1) != $(md5sum "$FILE2" | cut -d ' ' -f 1);
then
# Not same contents
exit;
fi
echo "Updating \"$FILE2\" from \"$FILE1\""
touch -r "$FILE1" "$FILE2"
第2部分:
使用“find”来递归查找文件,这可能是比较棘手的部分。
这还允许更高级的条件,包括指定修改日期,这样您就可以避免触摸绝对不应该触摸的东西,以确保安全和速度。请-mtime
参阅man find
。
例如,要查找最后修改时间戳为 1 年前或更早的所有文件:
find "DEST_DIRECTORY" -type f -mtime +365
其中 DEST_DIRECTORY 是您要修复的目录。选中此项将返回您要修复的文件。
第 3 部分:
将以上两部分结合起来。这有点棘手,因为需要将两个不同的文件传递给,这对于和copy_timestamp_if_identical.sh
来说并不容易。最后我决定编写一个辅助脚本:find
-exec
#!/bin/bash
# Usage: copy_timestamp_if_identical_helper.sh file_in_dest_dir source_dir dest_dir
test "$#" -eq 3 || { echo "Wrong number of arguments" >&2; exit 1; }
DEST_FILE="$1"
SRC_DIR="$2"
DEST_DIR="$3"
SRC_FILE="$SRC_DIR${DEST_FILE:${#DEST_DIR}}"
echo copy_timestamp_if_identical.sh "$SRC_FILE" "$DEST_FILE"
您必须将源目录和目标目录以及要修改的文件传递给它,因此组合解决方案如下所示:
find "DEST_DIR" -type f -mtime +365 -exec copy_timestamp_if_identical_helper.sh '{}' "SOURCE_DIR" "DEST_DIR" ';'