我的目录结构如下:
/books/a.epub
/books/sub/b.epub
/books/test/c.epub
我想找到所有根目录 (/books/) 和子目录 (/books/) 中的 .epub 文件/) 并使用 rsync 仅将 *.epub 文件复制到远程目录。
到目前为止我尝试过:
rsync -av --include='*.epub' --include='*/' --exclude='*' /media/share/Books/ /home/user/docker/calibre/books/
但它也在同步目录。
输出应该是这样的:
/a.epub
/b.epub
/c.epub
答案1
如果你有find
并且xargs
有空,你可以这样做:
find . -type f -iname "*.epub" -print0 | xargs -0 -I {} rsync -aPEmivv "{}" "/destination/directory"
如果你不想使用xargs
:
find . -type f -iname "*.epub" -exec rsync -aPEmivv "{}" "/destination/directory" \;
(两个变体都将在您的/books/
目录中运行)
不过,无论是您想要的-a
选项(递归、符号链接、预权限、保留时间、保留所有者、保留组、保留设备文件),都是您的决定。rsync
-rlptgoD
请注意,当将文件名通过管道传输到另一个程序时,建议使用空分隔字符串(对于空分隔输入,-print0
请使用 switch in find
、-0
inxargs
和in rsync
),这样文件名中的特殊字符就不会出现问题。
答案2
您是否有多个级别需要迭代?如果不?
rsync -aP books/*/*.epub books/*.epub /home/user/movedbooks/.
答案3
该rsync
实用程序可以从文件或输入流中读取路径名。您可以使用find
查找要复制的文件,然后使用rsync
.
我们假设您希望递归地搜索目录/media/share/Books
中任何名称与 shell 通配模式匹配的常规文件*.epub
。任何匹配这些条件的找到的文件都应复制到单个目录/home/user/docker/calibre/books
,而不创建在源层次结构中找到的相应目录结构:
find /media/share/Books -type f -name '*.epub' -print0 |
rsync --from0 --files-from=- \
--archive --no-relative \
/ /home/user/docker/calibre/books
我们上面使用的方式find
假设它支持非标准但普遍实现的-print0
谓词。如果没有,您可以替换-print0
为-exec printf '%s\0' {} +
。
请注意上面使用的选项rsync
。该--from0
选项将rsync
读取的数据流解释--files-from
为空分隔的路径名列表。使用-
with--files-from
表示“从标准输入流读取”,即从find
命令读取。我们使用--archive
选项 ( -a
) 来复制/同步每个文件尽可能多的元数据,并使用--no-relative
( --no-R
) 来丢弃读取路径名的目录路径部分。
使用的源目录rsync
是/
因为我们读取的路径名find
是相对于根目录的。
该管道执行rsync
一次并安全地在find
和之间传递路径名rsync
。您只需要注意,rsync
只需忽略与已列出的文件同名的其他文件即可解决名称冲突。
您也可以rsync
直接从find
using调用-exec
,但为了提高效率,我们可以使用 usefind
查找目录,然后调用rsync
同步*.epub
每个目录中的所有文件。
find /media/share/Books -type d -exec sh -c '
for dirpath do
rsync --archive \
--include="*.epub" --exclude="*" \
"$dirpath/" /home/user/docker/calibre/books
done' sh {} +
我们在这里所做的事情与您尝试过的类似,但通过排除处理目录来明确禁止递归。我们没有使用递归,而是rsync
将其外包给find
.