我的子文件夹中有一个 .bdf 文件。所有 .bdf 都具有相同的名称:Loads.bdf
例子:
/home/user/folderxx/folderxxx/Load.bdf
/home/user/folderxx/folderxxx/Load.bdf
我需要找到(并复制到新文件夹)所有 Load.bdf 文件并用其路径名重命名它们。
示例:在预期的操作之后,它应该显示类似这样的内容。
folder001_folderAAA_Load.bdf
folder002_folderBBB_Load.bdf
答案1
我将使用(“多次移动”)包mcp
中的工具:mmv
mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'
#1
第二个字符串中的等#2
将替换为第一个字符串中相应的第一个、第二个等通配符的内容。请注意,路径用单引号括起来,以便通配符由 解释mcp
,而不是由 shell 解释。
使用显示的命令,文件将被复制到当前目录。如果替换mcp
为mmv
,文件将被移动。
答案2
使用prename
(在许多系统上别名为rename
)可以在不多次运行mv
or的情况下完成此操作cp
:
cd /home/user
find . -type f -name 'Loads.bdf' -exec \
prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +
-n
当您确定这正在移动您想要的文件时,请删除。
更新
要复制文件而不是移动它们,最快的方法是先使用cpio
或pax
进行复制,然后像以前一样重命名。例如(使用 GNU cpio
):
cd /home/user
find . -type f -name 'Loads.bdf | cpio -p --make-directories destination
cd destination
find . -type f -name 'Loads.bdf' -exec prename -n 's:^./::; s:/:_:g' {} +
请注意,虽然pax
既是 POSIX 又是 LSB,并且cpio
不再是 POSIX,但cpio
仍然是许多系统中常见的程序。
find
要使用 GNU /处理带有换行符的文件名,cpio
可以添加-print0
到find
和-0
到cpio
.
更新2
解决pax
方案是一行(不包括cd
):
cd /home/user
find . -name 'Loads.bdf' | cut -d/ -f 2- | pax -rws ':/:_:g' destination
或者对于任何文件名(和 GNU find
):
find /home/user -name 'Loads.bdf' -printf '%P\0' | pax -0rws ':/:_:g' destination
答案3
如果您碰巧需要在没有其他一些答案中提到的工具(例如 mcp 和 mmv 或 prename)的系统上执行此操作,并且您想完全在 shell 中执行此操作,则可以执行某些操作喜欢:
#!/usr/bin/env bash
oldpath="/home/user"
newpath="/home/user/newfolder"
for file in $(find $oldpath -type f -name Load.bdf); do
shortname=${file#$oldpath/}
newname="$newpath/${shortname//\//_}"
if [ -f $newname ]; then
echo "$newname already exists."
else
echo "copy: $file"
echo " --> $newname"
cp $file $newname
fi
done
Load.bdf
该脚本将查找目录中指定的所有文件oldpath
,将目录名称合并为新文件名,然后将它们复制到目标目录。我们还可以检查已复制的文件是否存在,以防您需要多次运行它,并且我们不需要再次复制所有文件。
最终的目录结构将如下所示:
bash$ find . -type f
/home/user/folder001/folderAAA/Load.bdf
/home/user/folder002/folderBBB/Load.bdf
/home/user/folder003/folderCCC/Load.bdf
/home/user/newfolder/folder001_folderAAA_Load.bdf
/home/user/newfolder/folder002_folderBBB_Load.bdf
/home/user/newfolder/folder003_folderCCC_Load.bdf
答案4
env - sh <<\SCRIPT
t=/home/user/target f=folder
cd "${t%/*}" && mkdir -p "$t"
set -- $f??/$f???/Load.BDF
while [ -e "$1" ] ; do
cp "$1" "$t/$(IFS=/
printf '%s_%s_%s\n' $1)"
shift ; done
SCRIPT
我认为这都是完全可移植的 shell 脚本 - 尽管我一开始对此表示怀疑,但完成起来非常简单。