我的子資料夾中有一個 .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 腳本 - 儘管我一開始對此表示懷疑,但完成起來非常簡單。