Linux 在文件夹中查找文件并将其移动到带有时间前缀的新位置

Linux 在文件夹中查找文件并将其移动到带有时间前缀的新位置

我有一个可以通过 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;

相关内容