我想从当前目录复制文件,这些文件分为不同的子目录。我想要复制的文件应该只有True
和False
作为它们的父级。True
目录文件应复制到dst/report/1/
并且False
目录文件应位于dst/report/2/
.
我还不知道如何自动化复制过程:
我以为我可以使用
find . -maxdepth digit
但我不知道确切的深度是多少。这些文件应该只是
*.txt
文件,即使某些名称可能重复,但它们的内容不同,所以我需要在目标文件夹中使用它们中的任何一个,但cp
会覆盖它们。True
和False
中间父目录可能存在,但我想要的文件是在最后一个父目录中生成的。另外,目录空间大约为
200GiB
,因此搜索起来需要一段时间。我不确定目录和文件中的转义字符,所以我真的不想破坏复制过程。
样本工作空间:
```
__ current dir
|__ path_1
|__ True
|__ 00000.txt
|__ 020.txt
|__ p_x
|__ 100
|__ True
|__ 00000.txt
|__ 020.txt
|__ 10.txt
|__ False
|__ 1.txt
|__ 2.txt
|__ 200.txt
|__ x
|__ True
|__ 00000.txt
|__ 020.txt
|__ False
|__ 1.txt
|__ 2.txt
|__ True
|__ path_2
|__ True
|__ 1.txt
|__ x_p
|__ ...
|__ ...
.
.
.
预期成绩:
__ dst
|__ report
|__ 1
|__ 00000.txt
|__ 020.txt
|__ 00000_1.txt
|__ 020_1.txt
|__ 10.txt
|__ 1.txt
|__ 2
|__ 1.txt
|__ 2.txt
|__ 200.txt
|__ 1_1.txt
|__ 2_2.txt
更新
正如@muru 回答的那样,cp 可能很少,但它可以通过 bash ( ) 处理的参数数量受到限制getconf ARG_MAX
。
shopt -s globstar
cp --backup=numbered **/True/*.txt dst/report/1/
cp --backup=numbered **/False/*.txt dst/report/2/
所以当时,执行这些命令之后,就是得到-bash: /bin/cp: Argument list too long
回报。
正如 @muru 在评论中再次提到的,可以通过xargs
(假设 GNU xargs 和 cp)解决这个问题。
printf "%s\0" **/True/*.txt | xargs -0 cp --backup=numbered -t dst/report/1/
如果存在带有数字扩展名的重复文件(例如 bar.txt.~1~ 等),rename
则会很有用。
prename 's/(.txt).~(\d+)~$/-$2$1/' dst/report/*/*,
答案1
使用 bash,启用递归 glob **
with shopt -s globstar
,然后使用**/True/*.txt
and**/False/*.txt
作为模式,如果您有 GNU cp,请使用--backups
或-b
选项来避免覆盖文件:
shopt -s globstar
cp --backup=numbered **/True/*.txt dst/report/1/
cp --backup=numbered **/False/*.txt dst/report/2/
注意cp
会添加编号后扩展名:
% touch foo.txt
% cp foo.txt bar.txt
% cp --backup=numbered foo.txt bar.txt
% ls bar.txt*
bar.txt bar.txt.~1~
% cp --backup=numbered foo.txt bar.txt
% ls bar.txt*
bar.txt bar.txt.~1~ bar.txt.~2~