linux - 在当前目录中的所有目录和子目录中搜索与文件扩展名列表匹配的文件。将这些文件复制到维护文件结构的新目录
问题描述
我有一个包含一长串文件扩展名的文本文件:
.sln
.csproj
.cs
.xaml
.cshtml
.javasln
.project
.java
... (etc)
我有三个项目目录,每个目录都有许多子目录。
我可以通过以下方式获取所有文件和路径的列表:find . -type f -printf "%p\n"
./DirectoryA/src/main/resources/static/resources/build/home.ini
./DirectoryA/src/main/resources/static/resources/images/spring-pivotal-logo.png
./DirectoryB/src/main/resources/db/hsqldb/data.sql
./DirectoryC/src/main/resources/project/schema.project
我想遍历这些,如果文件扩展名与我列表中的一个匹配,请将其复制到myCopyDirectory
同时保持其目录结构。
也就是说,如果./DirectoryC/src/main/resources/project/schema.project
文件扩展名匹配.project
(就像它一样)作为我的文本文件中的扩展名之一......将它复制到一个新目录,./myCopyDirectory
如:./myCopyDirectory/DirectoryC/src/main/resources/project/schema.project
.
所以我需要一个 for 或 while 循环,请原谅我可怕的伪代码,但这是我的愿景
场景 1:动态复制文件
for FILE in `find . -type f -printf "%p\n"`; do if [ ${FILE##*.} in extensions.txt ]; then mkdir -p ./myCopyDirectory/DirectoryC/src/main/resources/project/ && cp ./DirectoryC/src/main/resources/project/schema.project ./myCopyDirectory/DirectoryC/src/main/resources/project/schema.project
场景 2:构建匹配的文件列表并复制它们
for FILE in `find . -type f -printf "%p\n"`; do if [ ${FILE##*.} in extensions.txt ]; then echo $FILE >> listOfFiles.txt
for FILE in `cat listOfFiles.txt`; do filename="${FILE##*/}" && dir="${FILE:0:${#FILE} - ${#filename}}" && if [ -e ./myCopyDirectory/$dir ]; then mkdir -p ./myCopyDirectory/$dir && cp $FILE ./myCopyDirectory
场景 3:只有cp -R
所有三个目录,./myCopyDirectory
并撕掉所有与 extensions.txt 文件中的扩展名不匹配的文件
请原谅我糟糕的伪代码。我只是想完成这项工作,而且有点超出我的深度。我可以创建一个 PERL 或 Python 脚本来执行此操作,但这似乎没有必要。
解决方案
您实际上不需要 for 循环;事实上,您可以利用find
's-exec
选项将复杂的 shell 命令传递给它来处理“目录保留”复制过程。
以下单行应该可以工作(解释如下)。
find root1 -regex '.*\.\(ext1\|ext2\)$' -exec sh -c 'dir=${1%/*}; dir=${dir/root1/root2}; file=${1##*/}; mkdir -p $dir && cp $1 $dir/$file' _ {} \;
我通过创建以下示例目录树对其进行了测试,
$ mkdir root1
$ mkdir root1/sub
$ mkdir root1/sub/dir
$ touch root1/a.ext1 root1/a.ext2 root1/a.ext3 root1/sub/a.ext1 root1/sub/a.ext2 root1/sub/a.ext3 root1/sub/dir/a.ext1 root1/sub/dir/a.ext2 root1/sub/dir/a.ext3
$ tree root1/
root1/
├── a.ext1
├── a.ext2
├── a.ext3
└── sub
├── a.ext1
├── a.ext2
├── a.ext3
└── dir
├── a.ext1
├── a.ext2
└── a.ext3
2 directories, 9 files
然后在其上执行命令并检查结果
$ find root1 -regex '.*\.\(ext1\|ext2\)$' -exec sh -c 'dir=${1%/*}; dir=${dir/root1/root2}; file=${1##*/}; mkdir -p $dir && cp $1 $dir/$file' _ {} \;
$ tree root2
root2
├── a.ext1
├── a.ext2
└── sub
├── a.ext1
├── a.ext2
└── dir
├── a.ext1
└── a.ext2
2 directories, 6 files
- 该
-regex
选项用于查找具有扩展名ext1
或的文件ext2
; - 该
-exec
选项用于对sh
找到的每个文件执行以下 ell 命令; - 该命令通过
-c
选项传递命令字符串,然后是参数的虚拟占位符,_
参数是由 找到的文件的名称;0
{}
find
1
- shell 命令字符串
dir
通过删除最后一个文件/
及其后面的任何内容$1
(已通过{}
)来提取每个文件的目录,- 然后通过替换
root2
来改变它root1
; - 同样,它提取文件名
file
; - 最后,它创建新的目录结构
mkdir
,并复制其中的文件。
我没有包含该-type f
选项,但如果您确实有扩展名等于您正在寻找的文件夹名称之一的文件夹名称,则可以。
推荐阅读
- javascript - TypeError:无法设置未定义的属性(设置“样式”)+在 next.config.js NextJS 中使用 withLess/withSass/withCSS
- python - 如何使字段可选?DRF
- amazon-web-services - 尝试将文件上传到 S3 存储桶时如何修复 InvalidArgument 错误 400?
- python - 关于在波斯真实国家网站(sheypoor)中抓取位置标签
- python - 终端中的 Scrapy shell 忽略 runner.py
- snowflake-cloud-data-platform - Snowpipe:仅加载第一行
- python - 转置并保存一列熊猫数据框
- python - 使用特殊规则过滤 django 中的对象
- python - Matplotlib:subplot2grid 中绘图外的颜色条
- javascript - 添加 chech/uncheck all 以过滤控制复选框输入