我有一个文件夹结构,其中有一堆* .csv文件分散在文件夹中。现在,我想将所有* .csv文件复制到另一个保留文件夹结构的位置。

它的工作方式是:上,但我想用一个命令来做。

#1 楼

find有一个非常方便的-exec选项:
find . -name '*.csv' -exec cp --parents \{\} /target \;


评论


可能因为这个\ {\} \;

– igo
2015年3月4日13:56

'{}'同样有效

–橙色狗
2015年12月7日在17:44

尽管-execdir比-exec更安全,但仅用-execdir替换一个并不能保持预期的文件夹结构。

–西门闪耀
16年8月23日在11:33

尝试使用您的命令复制它们时,为什么会收到消息“省略目录”?

– Vicky Dev
16-09-6在7:32

您能解释一下为什么必须在这里放括号吗?

–本体
16-10-23在3:26

#2 楼

您还可以为此使用rsync

$ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/


如果要保留源树中的空目录,请跳过--prune-empty-dirs选项:

$ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/


如果不想保留符号链接,修改日期,文件权限,所有者等,请用-a的另一种组合替换-rlptgoD。 ;-)

评论


-m是--prune-emty-dirs的快捷方式。

–老年病
16 Sep 24'0:59

另外,可以添加-R选项以复制源的父目录结构。 (请参阅我的回答。)

–老年病
16 Sep 24'1:52



-R对我有用!谢谢

–gigi2
19-10-17在13:10

#3 楼

您可以在直通模式下使用find和cpio

find . -name '*.csv' | cpio -pdm  /target


这将在当前目录及其下找到所有.csv文件,并将它们复制到/ target,以保持目录结构根源于.

如果使用

find /path/to/files -name '*.csv' | cpio -pdm /target


,它将找到/path/to/files及以下版本中的所有文件,并将其复制到/target/path/to/files及以下版本中。

评论


我尝试了从上到下的所有答案,这是唯一尝试过的答案

– OscarRyz
16年6月24日在19:10

这应该是公认的答案。

–菲利普·雷米(Philippe Remy)
20年8月25日,0:30

我发现GNU文档很有帮助:“在复制通过模式下,[-p选项要求cpio]从标准输入中读取要复制的文件列表;将其复制到的目录以非选项参数。” ... -d在需要的地方创建引导目录。 ... -m在创建文件时保留先前的文件修改时间。

– Nickolay
20/09/2在21:48



#4 楼

cp命令允许多个源参数:

cp **/*.csv --parents ../target


CAVEAT:我在这里使用递归glob;这是Bash 4+和globstar中的ksh选项,默认情况下在zsh中受支持。递归glob与隐藏的文件和文件夹不匹配,并且某些实现遵循符号链接,而另一些则不遵循符号链接。您可以执行以下操作:



*.csv */*.csv */*/*.csv */*/*/*.csv-当然这是非常多余的,并且需要知道您的目录结构有多深。

$(find . -name '*.csv') -这将匹配隐藏的文件和文件夹。 find还支持指定是否遵循符号链接,这可能很有用。


评论


这正是我尝试过的(递归glob),它找到了一些但不是全部?很奇怪。使用npm copyfiles脚本时,我得到的结果完全相同,但是如果我使用find命令,它将找到所有内容...

–兰迪亚
16年9月2日在15:22

@Randyaa我需要更多有关未找到哪些文件的详细信息,以帮助您。您可能会在这里找到讨论,并在此继续进行有关递归glob的精确行为的讨论。

–凯尔·斯特兰德(Kyle Strand)
16年9月2日在15:50

事实证明,由于某种原因未启用递归glob ...我以前从未遇到过此问题,但是我在执行命令之前立即执行一次shopt -s globstar来更正了它。感谢您的跟进!

–兰迪亚
16年9月2日在15:52

-父母是我想要的。谢谢

–乔什
19-10-3在22:35

#5 楼

这个为我工作:

find -name "*.csv" | xargs cp --parents -t /target

评论


使用最简单的语法的最佳答案。工作正常,很容易记住。在许多情况下,发现[事物] | xargs [执行任务]非常强大。

–真的
18/12/4在7:56



同意与其他答案相比,非常简单。

– Tim B
19年3月21日在12:40

如果文件名中有空格,则中断

–米歇尔·皮科利尼(Michele Piccolini)
19年9月16日14:58在

@MichelePiccolini可以使用find -print0和xargs -0处理文件名中的空格。

–pasztorpisti
19-09-19在15:22

#6 楼

来自rsync的联机帮助页:


-R,--relative

使用相对路径。这意味着在命令行上指定的完整路径名将发送到服务器,而不仅仅是文件名的最后一个
部分。当您要
同时发送多个不同的目录时,此功能特别有用。例如,如果
使用了以下命令:

rsync -av /foo/bar/baz.c remote:/tmp/


...这将在遥控器上的/ tmp /中创建一个名为baz.c的文件
机器。如果改为使用

rsync -avR /foo/bar/baz.c remote:/tmp/


,则将在远程
计算机上创建一个名为/tmp/foo/bar/baz.c的文件,并保留其完整内容。路径。这些额外的路径元素被称为“隐式目录”(即上例中的“ foo”和“ foo / bar”
目录)。


因此,这也将起作用:

rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/


评论


感谢您提供此答案。与BSD用户态(macOS)以及其中带有空格的路径兼容。

–myxal
20-2-14在9:57

#7 楼

假设您要将这个结构从./source复制到./destination

cd source
find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)


我准备将其视为一行,而cd source是内置的shell。

评论


tar具有-C选项,以避免必须先更改目录。

–巴特
16年11月4日,11:54