我创建了以下脚本,将定义的旧文件从源目录移动到目标目录。它工作得很好。
#!/bin/bash
echo "Enter Your Source Directory"
read soure
echo "Enter Your Destination Directory"
read destination
echo "Enter Days"
read days
find "$soure" -type f -mtime "-$days" -exec mv {} "$destination" \;
echo "Files which were $days Days old moved from $soure to $destination"
该脚本可以很好地移动文件,它还可以移动源子目录的文件,但不会在目标目录中创建子目录。我想在其中实现这个附加功能。
举例说明
/home/ketan : source directory
/home/ketan/hex : source subdirectory
/home/maxi : destination directory
当我运行此脚本时,它还会将十六进制的文件移动到 maxi 目录中,但我需要在 maxi 目录中创建相同的十六进制文件,并将其文件移动到相同的十六进制中。
答案1
我知道find
已指定,但这听起来像是rsync
.
例子
具有相同目录结构的镜像文件(源保持不变):
rsync -axuv --progress Source/ Target/
移动具有相同目录结构的文件(从源中删除并删除空目录):
rsync -axuv --prune-empty-dirs --remove-source-files --progress Source/ Target/
移动特定文件类型的文件(例子):
rsync -rv --include '*/' --include '*.js' --exclude '*' --prune-empty-dirs Source/ Target/
移动高级find
搜索产生的文件:
cd "$source" &&
rsync -av --remove-source-files --prune-empty-dirs --progress --files-from <(find . -type f -mtime -$days) . "$destination"
关于文件删除的说明
有一些选项rsync
可以确保您的目标目录镜像您的源目录,然后删除目标中不再位于源中的文件(即--delete-before
、--delete-after
、--delete-during
和--delete-delay
.
您还可以允许在文件从目标目录(即--remove-source-files
.
这取决于用例,因此如何处理取决于您。
笔记:正如 Sridar Sarnobat 指出的那样,如果您将一个带有符号链接的目录 rsync 到您要 rsync 的目录,和通过 --remove-source-files`,您最终可能会丢失数据。
答案2
mv /home/ketan/hex/foo /home/maxi
您需要根据 生成的路径更改目标目录,而不是运行find
。如果您首先更改到源目录并运行,这会更容易find .
。现在您只需将目标目录添加到 . 生成的每个项目的前面即可find
。您需要在find … -exec
命令中运行 shell 来执行串联,并在必要时创建目标目录。
destination=$(cd -- "$destination" && pwd) # make it an absolute path
cd -- "$source" &&
find . -type f -mtime "-$days" -exec sh -c '
mkdir -p "$0/${1%/*}"
mv "$1" "$0/$1"
' "$destination" {} \;
请注意,为避免$destination
包含特殊字符时出现引用问题,您不能仅在 shell 脚本中替换它。您可以将其导出到环境中,以便它到达内壳,或者您可以将其作为参数传递(这就是我所做的)。您可以通过对调用进行分组来节省一些执行时间sh
:
destination=$(cd -- "$destination" && pwd) # make it an absolute path
cd -- "$source" &&
find . -type f -mtime "-$days" -exec sh -c '
for x do
mkdir -p "$0/${x%/*}"
mv "$x" "$0/$x"
done
' "$destination" {} +
或者,在 zsh 中,您可以使用zmv
功能,以及.
和m
全局限定符仅匹配正确日期范围内的常规文件。如果需要,您需要传递一个mv
首先创建目标目录的备用函数。
autoload -U zmv
mkdir_mv () {
mkdir -p -- $3:h
mv -- $2 $3
}
zmv -Qw -p mkdir_mv $source/'**/*(.m-'$days')' '$destination/$1$2'
答案3
您可以使用 find(1) 的两个实例来完成此操作
总是有 cpio(1)
(cd "$soure" && find … | cpio -pdVmu "$destination")
检查 cpio 的参数。我给的那些
答案4
您可以通过将返回的文件的绝对路径附加find
到目标路径来完成此操作:
find "$soure" -type f -mtime "-$days" -print0 | xargs -0 -I {} sh -c '
file="{}"
destination="'"$destination"'"
mkdir -p "$destination/${file%/*}"
mv "$file" "$destination/$file"'