File 复制包含在不同父文件夹中的多个文件(同名)
我有一个关于unix命令行的问题。我有很多这样的文件:File 复制包含在不同父文件夹中的多个文件(同名),file,bash,unix,copy,File,Bash,Unix,Copy,我有一个关于unix命令行的问题。我有很多这样的文件: /f/f1/file.txt /f/f2/file.txt /f/f3/file.txt and so on. 我想把所有的file.txt和它们的父文件夹一起复制到另一个文件夹g中,比如: /g/f1/file.txt /g/f2/file.txt /g/f3/file.txt 我无法复制文件夹f的所有内容,因为在每个子文件夹f1、f2,…中,我还有许多其他文件不想复制 如何使用命令行执行此操作?最终使用bash脚本?tar
/f/f1/file.txt
/f/f2/file.txt
/f/f3/file.txt
and so on.
我想把所有的file.txt
和它们的父文件夹一起复制到另一个文件夹g中,比如:
/g/f1/file.txt
/g/f2/file.txt
/g/f3/file.txt
我无法复制文件夹f
的所有内容,因为在每个子文件夹f1、f2,…
中,我还有许多其他文件不想复制
如何使用命令行执行此操作?最终使用bash脚本?tar有时有助于处理文件:请参阅小测试:
kent$ tree t g
t
|-- t1
| |-- file
| `-- foo ---->####this file we won't copy
|-- t2
| `-- file
`-- t3
`-- file
g
3 directories, 4 files
kent$ cd t
kent$ find -name "file"|xargs tar -cf - | tar -xf - -C ../g
kent$ tree ../t ../g
../t
|-- t1
| |-- file
| `-- foo
|-- t2
| `-- file
`-- t3
`-- file
../g
|-- t1
| `-- file
|-- t2
| `-- file
`-- t3
`-- file
这似乎会帮助你:
find /f/ -name file.txt -execdir cp -R . /g/ \;
它在目录/f/中定位所有名为file.txt的文件,然后使用execdir(在包含匹配文件的目录中执行)将包含该文件的目录复制到目录/g/手动for
cp
显示此选项-
--parents
use full source file name under DIRECTORY
因此,如果您在bashv4
上,您可以执行类似的操作-
[jaypal:~/Temp/f] tree
.
├── f1
│ ├── file.txt # copy this file only with parent directory f1
│ ├── file1.txt
│ └── file2.txt
└── f2
├── file.txt # copy this file only with parent directory f2
├── file1.txt
└── file2.txt
2 directories, 6 files
[jaypal:~/Temp/f] mkdir ../g
[jaypal:~/Temp/f] shopt -s globstar
[jaypal:~/Temp/f] for file in ./**/file.txt; do cp --parents "$file" ../g ; done
[jaypal:~/Temp/f] tree ../g
../g
├── f1
│ └── file.txt
└── f2
└── file.txt
2 directories, 2 files
看一看。假设您在“/”中
rsync -r f/ g/ --include "*/" --include "*/file.txt" --exclude "*"
第一个include是告诉rsync查看子目录内部(并抵消最后一个exclude)所必需的。第二个包含选择要复制的文件。“排除”确保不会在/f中处理不属于所需模式的其他文件
注意:如果您有符号链接,rsync将复制链接,而不是链接指向的文件,除非您指定了--copy links
例如:
$ find f g -type f
f/f1/file.txt
f/f1/fileNew.txt
f/f2/file.txt
f/f3/file.txt
find: g: No such file or directory
$ rsync -r f/ g/ --include "*/" --include "*/file.txt" --exclude "*"
$ find f g -type f
f/f1/file.txt
f/f1/fileNew.txt
f/f2/file.txt
f/f3/file.txt
g/f1/file.txt
g/f2/file.txt
g/f3/file.txt
非常感谢你!这就像我希望的那样!谢谢你的回答@fibon82:对于你的具体情况,这可能是最简单的,但是要记住rsync,因为它非常强大,特别是对于更复杂的情况。好的,卡洛斯。谢谢你的建议@杰帕尔:+1,因为我不知道--parents。@杰帕尔+1。是否可以用简单的
cp--parents./**/file.txt../g
替换for
循环?据我所知,该命令将文件复制到/g/而不保留相对路径,例如/g/f1/file.txt,并将覆盖现有的file.txt,即您最终在/g/中赢得一个文件,最后一个被复制的文件。我错过什么了吗?是的,没错。我将帖子从cp
编辑为cp-R
,这在复制目录时显然更有意义。我不认为问题与-R有关。我在Mac OS X(即BSD unix)上运行了您的代码,最终得到了/g/文件的联合,与复制的最后一个文件对应的任何给定名称。+1我从未想过使用tar
进行move
。杰出的解释也很清楚;-)