如何移动子目录中早于 x 天的文件?

如何移动子目录中早于 x 天的文件?

基本上我想这样做:

mv /path/sourcefolder/* /path/destinationfolder/

但仅限于 90 天以上的文件。

如果需要,MV 必须复制源路径的子目录结构。 MV 仅移动超过 90 天的文件。

这样的事情是行不通的。它确实将所有文件放在同一目标文件夹中,而不考虑源子目录结构。

find -type f -mtime +600 -exec mv '{}' /storage/9016-4EF8/WhatsApp/Media/ \;

答案1

使用zsh,您可以执行以下操作:

dest=/storage/9016-4EF8/WhatsApp/Media
cd /path/sourcefolder &&
  for f (**/*(ND.m+89)) {
    mkdir -p -- $dest/$f:h &&
      mv -- $f $dest/$f
  }

zmodload zsh/files您可以通过预先发布一个将替换mvmkdir的内置版本来加快速度。

或者 POSIXly:

cd /path/sourcefolder &&
  dest=/storage/9016-4EF8/WhatsApp/Media find . -type f -mtime +89 -exec sh -c '
     for f do
       mkdir -p -- "$dest/${f%/*}" &&
         mv -- "$f" "$dest/$f"
     done' sh {} +

(注意:-mtime -89选择小于 89 天的文件、-mtime 8989 至 90 天的文件以及90 天或更早的文件(或至少在启动-mtime +89时) ,请注意,此处find指的是 24 小时周期,无论该时间间隔内是否有 DST 时钟更改))。

在任何情况下,请注意,虽然mv在将原始文件复制到外部介质时会尝试保留原始文件的大部分属性,但目录本身将在此处创建为新目录,并具有默认的所有权、权限和属性(不太可能成为问题)你的情况是目标文件夹听起来并不好,甚至在类 Unix 文件系统上也是如此)。

答案2

该脚本适用于带有空格的目录/文件名。这里的情况是,它打印命令而不是执行命令。如果您想实际执行命令,请从代码中删除“echo”一词(在两个位置)。

Oneliner 使用 shell(/bin/sh 或 /bin/bash)执行:

DAYS=89; SOURCE="/path/sourcefolder/"; DEST="/path/destinationfolder/"; find "${SOURCE}" -mtime +${DAYS}|while read -r S; do D=$(echo "${S}"|sed "s#^${SOURCE}#${DEST}#g"); DD=$(dirname "${D}"); [ -d "${DD}" ] || echo mkdir -p \"${DD}\"; echo mv -f \"${S}\" \"${D}\"; done

解释:

# define number of days
DAYS=89;
# source directory
SOURCE="/path/sourcefolder/";
# destination directory
DEST="/path/destinationfolder/";
# take one by one all files from source directory
find "${SOURCE}" -mtime +${DAYS}|while read -r S; do
   # create destination file path, based on source file path
   D=$(echo "${S}"|sed "s#^${SOURCE}#${DEST}#g");
   # find directory, where distination file should be placed
   DD=$(dirname "${D}");
   # if destination directory does not exist, create it
   [ -d "${DD}" ] || echo mkdir -p \"${DD}\";
   # move source file to destination
   echo mv -f \"${S}\" \"${D}\";
done

相关内容