在UNIX bash shell(特别是Mac OS X Leopard)上,将具有特定扩展名的每个文件从文件夹层次结构(包括子目录)复制到同一目标文件夹(没有子文件夹)的最简单方法是什么?
显然存在源层次结构中存在重复的问题.我不介意他们被覆盖.
示例:我需要复制以下层次结构中的每个.txt文件
/foo/a.txt /foo/x.jpg /foo/bar/a.txt /foo/bar/c.jpg /foo/bar/b.txt
到名为'dest'的文件夹并获取:
/dest/a.txt /dest/b.txt
Magnus Hoff.. 53
在bash中:
find /foo -iname '*.txt' -exec cp \{\} /dest/ \;
find
将找到/foo
匹配通配符的路径下的所有文件*.txt
,不区分大小写(这就是-iname
意味着什么).对于每个文件,find
将执行cp {} /dest/
,找到的文件代替{}
.
在bash中:
find /foo -iname '*.txt' -exec cp \{\} /dest/ \;
find
将找到/foo
匹配通配符的路径下的所有文件*.txt
,不区分大小写(这就是-iname
意味着什么).对于每个文件,find
将执行cp {} /dest/
,找到的文件代替{}
.
Magnus解决方案的唯一问题是它为每个文件分配了一个新的"cp"进程,这不是特别有效,特别是如果有大量文件的话.
在Linux(或其他具有GNU coreutils的系统)上,您可以:
find . -name "*.xml" -print0 | xargs -0 echo cp -t a
(-0允许它在文件名中包含奇怪的字符(如空格)时工作.)
不幸的是,我认为Macs配备了BSD风格的工具.有人知道"标准"等同于"-t"开关吗?
The answers above don't allow for name collisions as the asker didn't mind files being over-written.
I do mind files being over-written so came up with a different approach. Replacing each/in the path with - keep the hierarchy in the names, and puts all the files in one flat folder.
We use find to get the list of all files, then awk to create a mv command with the original filename and the modified filename then pass those to bash to be executed.
find ./from -type f | awk '{ str=$0; sub(/\.\//, "", str); gsub(/\//, "-", str); print "mv " $0 " ./to/" str }' | bash
where ./from and ./to are directories to mv from and to.