根据子目录名称将文件从特定子目录复制到单个目录然后重命名

根据子目录名称将文件从特定子目录复制到单个目录然后重命名

这是我的目录树的摘录:

|-- 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

该命令生成的目标文件名cptest/20070214_014700_AZ.AS..HHZ.

相关内容