我有以下目录结构:
dir1
py1.py
py2.py
subdir1
file1.py
anotherfile.txt
subdir2
file2.py
animage.png
Run Code Online (Sandbox Code Playgroud)
我想将文件夹结构和 *.py 文件(除了那些直接属于 dir1 的文件)复制到与 dir1 相同级别的新目录中。也就是说,我正在寻找这个:
dir2
subdir1
file1.py
subdir2
file2.py
Run Code Online (Sandbox Code Playgroud)
我试过(从 dir1 上面的层):
mkdir dir2
cp -r *.py ../dir2
Run Code Online (Sandbox Code Playgroud)
但这只是将 *.py 文件从 dir 1 复制到 dir2,而忽略了子目录。
您可以使用findand来完成此操作cpio,只需cd进入dir1并运行以下命令:
find . -mindepth 2 -type f -name "*.py" -print | cpio -pdm ../dir2
Run Code Online (Sandbox Code Playgroud)
find .将从当前目录开始,即。dir1-mindepth 2将忽略当前目录的内容,即。dir1并包含其子目录的内容。-type f -name "*.py" -print将仅包含具有.py扩展名的文件。cpio -pdm会复制。-p创建文件列表,-d根据需要创建目录并-m设置目录的正确修改时间。
../dir2dir2将创建一个名为旁边一级的目录(如果不存在)dir1并将所有内容复制到其中。
祝你好运
小智 0
好吧,我找不到一种方法让 cp 或 rsync 自己做你想做的事,所以我想出了:
for n in dir1/* ; do ls ${n}/*.py >/dev/null 2>&1 ; if [[ $? == 0 ]]; then mkdir dir2/${n/dir1\//} ; cp ${n}/*.py dir2/${n/dir1\//} ; fi ; done
Run Code Online (Sandbox Code Playgroud)
正确缩进可以使其更具可读性:
for n in dir1/*
do
ls ${n}/*.py >/dev/null 2>&1
if [[ $? == 0 ]]
then
mkdir dir2/${n/dir1\//}
cp ${n}/*.py dir2/${n/dir1\//}
fi
done
Run Code Online (Sandbox Code Playgroud)
所以,我正在做的是查看 dir1,假设每个文件都是一个目录,并尝试列出所有 *.py 文件(输出和错误消失在 /dev/null 中)。显然,对 py1.py 和 py2.py 尝试此操作将会失败,因为它们不是目录。对于其中没有任何 *.py 文件的任何目录,它也应该失败。
这意味着当我们在 if 中时,前一个命令 ($?) 的结果应该不是 0,并且我们什么也不做。对于 dir1 中的子目录,列表应该成功,所以 $? 将为 0,因此我们在循环内执行该位。这只是在 dir2 中创建子目录(记住将“dir1/”替换为空),并复制所有 *.py 文件。
这当然不是执行此操作的唯一方法,虽然它适用于您给出的示例,但如果子目录中有额外级别的子目录,则它不起作用。(例如dir1/subdir1/subsubdir1/*.py不会被复制)