这是我的目录树的摘录:
|-- 20070214_014700.a
| |-- info
| |-- processed
| |-- HH.EL..BHZ
| |-- AZ.AS..HHZ
| |-- (hundreds more)
| |-- raw
| |-- resp
|-- 20100737_055560.a
| |-- info
| |-- processed
| |-- raw
| |-- resp
|-- 20190537_028750.a
| |-- info
| |-- processed
| |-- raw
| |-- resp
我有大约 13,000 个目录(以 .a 结尾),每个目录都有一个“已处理”子目录,其中包含我想从每个已处理/目录复制到单个目录中的文件。其中一些文件可能具有相同的文件名,因此我还想根据其父目录重命名它们。我不太挑剔,但类似于:
20070214_014700_HH.EL..BHZ
整个数据集为 3 TB,因此我仅使用“查找”在几个目录上进行了测试:
find . -name processed -exec cp -r '{}' 'test/{}' \;
由于某种原因,这会将一些文件转储到 test/ 中,但也会在其中创建另一个processed/ 目录。我不确定如何同时将复制命令和重命名函数包含到 find 中,因此任何建议都会很棒。谢谢您的帮助。
答案1
find . -type f -path "./*.a/processed/*" -exec sh -c '
for path; do
prefix=${path%%.a/processed*}
cp "$path" "test/${prefix##*/}_${path##*processed/}"
done
' sh {} +
选项-type f
在给定路径中搜索常规文件,并且该-exec
选项启动一个 shell 脚本,并将find
结果作为参数 ( {} +
)。在for
循环中,每个参数都分配给path
变量。
示例:如果变量path
是./20070214_014700.a/processed/AZ.AS..HHZ
,则
prefix=${path%%.a/processed*}
删除后缀 ->./20070214_014700
${prefix##*/}
/
删除第一个->的前缀20070214_014700
${path##*processed/}
还删除了前缀并保留文件名 ->AZ.AS..HHZ
该命令生成的目标文件名cp
是test/20070214_014700_AZ.AS..HHZ
.