如何通过文件扩展名递归复制文件,同时保留目录结构?


71

在Linux命令行上,我想将一组(很大).txt文件从一个目录(及其子目录)复制到另一个目录。

我需要目录结构保持完整,并且需要忽略文件(以结尾的文件除外).txt


2
在您的问题中使用cp和find作为标签,是否意味着您就被这些选项束缚了?由于您的数据集非常大,因此有理由假设复制过程可能由于某些原因而中断,因此您必须重新启动它。我不确定find / cp方法是否能够继续传输并仅复制缺少的部分。如果您不依赖于find / cp,则可以考虑使用rsync,它更智能。其--exclude选项可让您跳过.txt文件。
vtest

公平电话-rsync可能是更好的选择。不依赖于find / cp。(无论如何,我还是使用了它们-rsync尚未安装在远程计算机上,它是一台实时Web服务器,我希望尽可能减少占用的空间)
无人认领的

Answers:


95

您可以使用findcpio来执行此操作

cd /top/level/to/copy
find . -name '*.txt' | cpio -pdm /path/to/destdir

(-updm for overwrite destination content.)

为什么是米?我认为它只是保留文件修改日期。
Mubashar

7
cd /source/path
find -type f -name \*.txt -exec install -D {} /dest/path/{} \;

你错过了.之后find。同样在macOS 10.13.1上,它也可以:find . -type f -name "*.txt" -exec install -v {} /dest/path/{} \;
严峻

2

另一种方法

find . -name '*.txt' -exec rsync -R {} path/to/dext \;


我喜欢这个解决方案。我曾经find . -iname '*.txt' -exec rsync -Rptgon {} path/to/dext \;做过不区分大小写的匹配,并保留了所有者和权限。
MountainX

1

对我有效的最简单方法是:

cp --parents -R jobs/**/*.xml ./backup/

一个陷阱是,您必须先导航到“所需”目录,以便“父路径”正确。

还要确保在bash中启用了递归glob:

shopt -s globstar

1

你怎么样先用

cp -r /old/folder /new/folder

然后转到新文件夹并运行

find . -type f ! -iname "*.txt" -delete

要不就

cp -r /old/folder /new/folder && find . -type f ! -iname "*.txt" -delete

编辑:好的,您想要一个可以过滤的命令(我尚未测试此命令,因为我的系统没有该cpio命令!)。我在这里找到它的地方:http : //www.gnu.org/software/findutils/manual/html_mono/find.html#Copying-A-Subset-of-Files

find . -name "*.txt" -print0 |
     cpio -pmd0 /dest-dir

请先进行测试,因为我还没有尝试过。如果有人可以验证,那就太好了。


点头打气-这行得通,但如果不过滤到.txt,我正在查看的文件数为几百万个(文件大小为数百GB)。如果需要,我可能不得不这样做,但我希望尽可能在复制时进行过滤
无人认领的

1
干杯,如果我从-pmd0删除“ 0”
无人认领的

您应该保留0in -pmd0并将其添加-print0find命令的末尾(恰好在之前|)。
G-Man

1

我试图在macOS上做同样的事情,但是没有一个选项真正适合我。直到我发现ditto

我不得不复制许多.wav文件,并跳过视频文件...所以这是我想出的:

find . -type f -iname "*.wav" -ls -exec ditto {} /destination/folder/{} \;

  • find .-在当前文件夹中运行查找。cd /source/folder开始之前请确保您

  • -type f -指定仅查找文件

  • -iname "*.wav" -这告诉它寻找不区分大小写的* .wav
  • -ls-这将显示正在处理的文件。否则它什么也没显示。
  • -exec ditto {} /destination/folder/{} \; -完成所有复制和创建具有相同目录树的文件的工作。

0

导航到目录:

find . -regex '<regexp_to_get_directories_and_files_you_want>' | xargs -i cp -r --parents {} path/to/destination

如果您管理正则表达式,则可能会更加直接和强大。


-1

导航到目录:

cp '*.css' /path/to/destination

您必须导航到目录中的每个文件夹,但这比我到目前为止看到的大多数选项都要好。


此方法不是递归的,这意味着对于大型目录,您可能会花相当长的时间...
Iain Reid
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.