基本上我想这样做:
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
您可以通过预先发布一个将替换mv
和mkdir
的内置版本来加快速度。
或者 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 89
89 至 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