'find -exec mv' 尝试移动它之前移动的同一个文件

Lun*_*ist 5 backup find mv

我的错误命令:

find . -type f -name '*2019*' -exec mv {} ./backup_2019 \;
Run Code Online (Sandbox Code Playgroud)

结果 :

mv: ‘./backup_2019/2019-A.txt’ and ‘backup_2019/2019-A.txt’ are the same file
mv: ‘./backup_2019/2019-B.txt’ and ‘backup_2019/2019-B.txt’ are the same file
mv: ‘./backup_2019/2019-C.txt’ and ‘backup_2019/2019-C.txt’ are the same file
Run Code Online (Sandbox Code Playgroud)

我认为它找到了它之前移动的文件。我可以在不使用 maxdepth 的情况下解决这个问题吗?有没有办法只排除目标目录?

roa*_*ima 6

您应该忽略要排除的目标目录

find . -path './backup_2019' -prune -o -type f -name '*2019*' -exec mv {} ./backup_2019 \;
Run Code Online (Sandbox Code Playgroud)

运算符之间的隐式 AND 比 OR ( -o)绑定得更紧密,因此它转换为(如果路径匹配则跳过./backup_2019) OR (mv如果我们有文件匹配*2019*)


Kus*_*nda 5

您将需要忽略备份目录,以免find进入其中。已经有一个答案显示了如何做到这一点。

但是,如果您以这种方式备份文件,您可能会面临删除数据的风险。如果不同子目录中的两个或多个文件具有相同的名称,它们将在目标备份目录中相互覆盖。

最好使用一些真正的备份软件来备份数据,例如restic. 如果这是不可能的,请使用保留您正在备份的文件的相对路径的解决方案。

以下命令用于rsync将名称包含子字符串的所有文件复制(而不是移动)2019到目录中backup_2019

rsync --itemize-changes --archive --prune-empty-dirs \
    --exclude='/backup_2019/***' --include='*/' --include='*2019*' --exclude='*' \
    ./ ./backup_2019
Run Code Online (Sandbox Code Playgroud)

这将避免在内部./backup_2019查找要传输的文件或目录,否则会复制包含 substring 的所有内容2019。目标上最终为空的目录将被删除。复制的所有内容都复制到backup_2019与当前目录下文件位置相同的位置:

例子:

$ tree -F
.
|-- dir1/
|   |-- file-1
|   |-- file-2019-A
|   `-- subdir/
|       |-- file-2
|       `-- file-2019-B
|-- dir2/
|   |-- file-1
|   |-- file-2019-A
|   `-- subdir/
|       |-- file-2
|       `-- file-2019-B
`-- dir3/
    |-- file-1
    |-- file-2019-A
    `-- subdir/
        |-- file-2
        `-- file-2019-B
Run Code Online (Sandbox Code Playgroud)
$ rsync --itemize-changes --archive \
    --prune-empty-dirs \
    --exclude='/backup_2019/***' --include='*/' --include='*2019*' --exclude='*' \
    ./ ./backup_2019
cd+++++++++ ./
cd+++++++++ dir1/
>f+++++++++ dir1/file-2019-A
cd+++++++++ dir1/subdir/
>f+++++++++ dir1/subdir/file-2019-B
cd+++++++++ dir2/
>f+++++++++ dir2/file-2019-A
cd+++++++++ dir2/subdir/
>f+++++++++ dir2/subdir/file-2019-B
cd+++++++++ dir3/
>f+++++++++ dir3/file-2019-A
cd+++++++++ dir3/subdir/
>f+++++++++ dir3/subdir/file-2019-B
Run Code Online (Sandbox Code Playgroud)
$ tree -F
.
|-- backup_2019/
|   |-- dir1/
|   |   |-- file-2019-A
|   |   `-- subdir/
|   |       `-- file-2019-B
|   |-- dir2/
|   |   |-- file-2019-A
|   |   `-- subdir/
|   |       `-- file-2019-B
|   `-- dir3/
|       |-- file-2019-A
|       `-- subdir/
|           `-- file-2019-B
|-- dir1/
|   |-- file-1
|   |-- file-2019-A
|   `-- subdir/
|       |-- file-2
|       `-- file-2019-B
|-- dir2/
|   |-- file-1
|   |-- file-2019-A
|   `-- subdir/
|       |-- file-2
|       `-- file-2019-B
`-- dir3/
    |-- file-1
    |-- file-2019-A
    `-- subdir/
        |-- file-2
        `-- file-2019-B

13 directories, 18 files
Run Code Online (Sandbox Code Playgroud)

您可以添加--remove-source-filesrsync选项列表中以对您备份的文件执行“移动”而不是“复制”。