将所有子目录名称和具有特定扩展名的文件复制到新目录

将所有子目录名称和具有特定扩展名的文件复制到新目录

我有以下目录结构:

dir1
    py1.py
    py2.py
    subdir1
        file1.py
        anotherfile.txt
    subdir2
        file2.py
        animage.png

我想将文件夹结构和 *.py 文件(除了直接属于 dir1 的文件)复制到与 dir1 同级的新目录中。也就是说,我正在寻找以下内容:

dir2
    subdir1
        file1.py
    subdir2
        file2.py

我尝试过(从 dir1 上方的层):

mkdir dir2
cp -r *.py ../dir2

但这只将 *.py 文件从目录 1 复制到目录 2,而忽略了子目录。

答案1

您可以使用 shell glob,并可以--parents选择cp

例如给定

$ tree dir1 dir2
dir1
├── py1.py
├── py2.py
├── subdir1
│   ├── anotherfile.txt
│   └── file1.py
└── subdir2
    ├── animage.png
    └── file2.py
dir2

2 directories, 6 files

(注意dir2已经存在)然后

$ cd dir1
$ cp --parents -t ../dir2 **/*.py
$ cd ..

给出

$ tree dir1 dir2
dir1
├── py1.py
├── py2.py
├── subdir1
│   ├── anotherfile.txt
│   └── file1.py
└── subdir2
    ├── animage.png
    └── file2.py
dir2
├── subdir1
│   └── file1.py
└── subdir2
    └── file2.py

4 directories, 8 files

我使用了globstar模式**,但如果您只需要下降一个级别,您可以*对子目录使用基本通配符。

答案2

您可以使用和来完成此操作findcpio只需cd进入dir1并运行此操作:

find . -mindepth 2 -type f -name "*.py" -print | cpio -pdm ../dir2
  • find .将从当前目录即启动。dir1
  • -mindepth 2将忽略当前目录的内容,即dir1并包括其子目录的内容。
  • -type f -name "*.py" -print将仅包含.py扩展名的文件。
  • cpio -pdm将复制。-p创建文件列表,-d根据需要创建目录并-m在目录上设置正确的修改时间。

  • ../dir2dir2将创建一个名为上一级的目录(如果不存在),dir1并将所有内容复制到其中。

以供参考男人找到人cpio

祝你好运

答案3

使用rsync

mkdir dir2
rsync -amv --include '*/' --include '*/*.py' --exclude '*' dir1/ dir2

.py将从第二级开始复制所有文件。

  • -m避免创建空目录。
  • --include '*/'包括所有目录
  • --include '*/*.py'包括.py从第二级开始的所有文件
    • 如果'/*/*.py'您想包含仅有的二级.py文件
  • --exclude '*'排除所有未包含的内容。

答案4

好的,我找不到让 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

适当缩进可以使其更具可读性:

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

因此,我所做的是查看 dir1,假设每个文件都是一个目录,并尝试列出任何 *.py 文件(输出和错误消失在 /dev/null 中)。显然,对 py1.py 和 py2.py 尝试此操作将失败,因为它们不是目录。对于其中没有任何 *.py 文件的目录,它也应该会失败。

这意味着当我们处于 if 中时,前一个命令 ($?) 的结果应该不是 0,我们什么也不做。对于 dir1 中的子目录,列表应该成功,因此 $? 将为 0,因此我们在循环内执行该位。这只会在 dir2 中创建子目录(记住将“dir1/”替换为空),并复制所有 *.py 文件。

这当然不是唯一的方法,虽然它适用于你给出的例子,但如果子目录内有额外的子目录级别,它就不起作用。(dir1/subdir1/subsubdir1/*.py例如不是可复制)

相关内容