我有一个可以通过 sftp 访问的备份文件夹。想法是备份进入这个文件夹但不应该留在那里。我想用 cron 作业移动它们。这已经是可能的,但由于我不能确定文件名是否唯一,所以我想在移动文件时给它添加前缀。
* * * * * find /src/backup/ -mmin +60 -exec mv "{}" /dest/backup/ \;
我怎样才能修改命令,使得文件本身获得前缀
(例如)yyyymmdd-MMSS-
或者使用新文件夹(例如)yyyymmdd
?
答案1
您将需要脚本来执行此操作,因此您不能-exec
直接使用选项执行此操作(除非您使用bash -c
,这会使引用和参数扩展变得困难)。
有两种选择:-
- 使用
find /src/backup/ | while read -r f; do ...; done
- 如果您有普通文件名(没有前导/尾随空格,也没有嵌入的新行),这将起作用。 - 调用包含您需要的命令的脚本文件,例如
find /src/backup/ -mmin +60 -exec /Path/To/moveunique {} /dest/backup/
- 在这种情况下,我建议将完整的脚本路径放入行中crontab
,因为它的环境与您的交互式 shell 不同。
我将说明第一个选项:如何在脚本文件中使用类似的命令应该是显而易见的:
find /src/backup/ | while read -r f; do \
mv "$f" /dest/backup/"${f%/*}"/$(date -d@$(stat "$f" -c %Y) +'%Y%m%d-%H%M')-"${f##*/}"; \
done
这用于stat
获取文件的修改时间,date
格式化所需的时间字段,以及参数扩展以分隔文件的目录路径和名称。
这会产生一个相当长的命令字符串(我使用了连续行来使其更具可读性,并且我还没有检查是否crontab
支持这一点),因此您更喜欢使用脚本。
答案2
所以因为无论如何我都需要一些灵活性,所以我根据 AFH 的想法想出了一个脚本版本。
#!/bin/sh
# configure: source path
source_path="/src/path/backup";
# configure: destination path
destination_path="/dest/path/backup";
# find all files in source_path not modified in the last 60 minutes
find $source_path -mmin +60 -type f | while read -r file; do
# this is the absolute source path (/src/path/backup/path/to/file)
absolute_source_path="${file%/*}";
# get the relative source path (/path/to/file)
relative_source_path=${absolute_source_path#$source_path}
# get the last modification date of the file (yyyymmdd)
file_save_date="$(date -d@$(stat "$file" -c %Y) +'%Y%m%d')";
# IMPORTANT create sub directory at the destination if required
mkdir --parents "$destination_path/$file_save_date$relative_source_path/";
# move the file to new destination (/dest/path/backup/yyyymmdd/path/to/file)
mv "$file" "$destination_path/$file_save_date$relative_source_path/" > /dev/null 2>&1;
done
# delete empty folders if the the folder is not changes in the last 5 minutes
find $source_path/* -mmin +5 -type d -empty -delete > /dev/null 2>&1;