将不同文件夹中的同名文件移动到一个文件夹

将不同文件夹中的同名文件移动到一个文件夹

我有多个代表参与者的文件夹,每个文件夹都有一个名为con_0001.img。我想移动所有这些文件(con_0001.img)到一个新文件夹(而不是将它们放在各个参与者文件夹中)。

下面的代码似乎发现con_0001.img并将其移动到一个名为的新文件夹SA_A

find . -name "con_0001.img" -exec mv '{}' "./SA_A/" ";"

然而,由于所有文件都被命名为con_0001.img,我最终只有新文件夹中的一个文件(大概是因为所有后续文件都会相互覆盖)。

我确实设法找到了防止这种覆盖的建议,即:

find . -name "con_0001.img" -exec mv --backup=numbered "{}" "./SA_A/" \;

然而,我最终还是得到了一个文件con_0001.img已从多个文件夹中消失,因此它似乎被覆盖。如果我更改mvcp,我最终也会得到一个文件(但文件保留在原处,正如您复制文件所期望的那样)。

有没有办法避免这种覆盖?更理想的是,有没有办法在文件移动到新文件夹时将其父目录(参与者编号)的部分名称添加到文件中?例如:

p102/con_0001.img ----> p102_con_0001.img

p105/con_0001.img ----> p105_con_0001.img

我尝试调整以下代码,因为它似乎应该将父目录添加到移动的文件中:

find . -name 'con_0001.img' | while read filePath; do cp "$filePath" './SA_A'/"$(echo "$filePath")"; done

但是,它返回一个错误:

无法创建常规文件“/SA_A/./p105/con_0001.img”:没有这样的文件或目录

我的新文件夹后似乎有一个意外的句号/SA_A/。这可能是代码不起作用的原因?这个句号是从哪里来的?

答案1

mkdir SA_A
find . -name "con_0001.img" -exec sh -c '
    for f; do d=${f%/*}; mv -- "$f" "./SA_A/${d#./}${f##*/}"; done
' findsh {} +

for 循环遍历每个找到的文件。

  • d=${f%/*}删除 的最右边/*部分f,即文件的基本名称。
  • ${d#./}./删除文件的前导。
  • ${f##*/}获取文件的基本名称,删除最后一个/.

执行前:

$ ls a1 a2 a3
a1:
con_0001.img

a2:
con_0001.img

a3:
con_0001.img

执行后:

$ ls a1 a2 a3 SA_A/
a1:

a2:

a3:

SA_A/:
a1con_0001.img  a2con_0001.img  a3con_0001.img

但使用单个 shell 循环就更简单了:

for f in */con_0001.img; do
    mv -- "$f" "./SA_A/${f%/*}_${f#*/}"
done

相关内容