[英]Bash script to rename folders recursively
我想重命名這些文件夾中的所有文件夾和文件夾,以便文件夾名稱中的所有下划線都替換為空格。 你能幫幫我嗎?
使用-execdir
的答案比較簡單,但只適用於支持-execdir
的find
版本,例如GNU find,因為POSIX只指定-exec
。
如果你只是想使用bash,那么要想做到這一點非常棘手,因為你正在重命名find
的目錄。 即使您通過使用-depth
選項find
正確的順序,也需要確保只使用每個-exec
重寫路徑的最后一個組件。 以下是Bash常見問題解答中給出的一個示例的一個微不足道的變體,似乎對我有用:
find . -depth -name "*_*" -exec bash -c 'dir=${1%/*} base=${1##*/}; mv "$1" "$dir/${base//_/ }"' _ {} \;
該FAQ答案有更多關於遞歸命名文件夾的問題的討論,這可能是有意義的。
更新 :由於這種單線程相當復雜,為了解釋起見,可能值得將其分解一點。 基本上, find
命令是:
find . -depth -name "*_*" -exec bash -c [SOME-STUFF] _ {} \;
換句話說,找到包含下划線的所有目錄,並且對於每個這樣的目錄,從最深處開始,運行bash腳本[SOME-STUFF]
,參數0為_
(表示我們不關心它)和參數1作為找到的文件的名稱。 ( find
會在-exec
之后用{}
替換文件名。 \\;
只是終止-exec
運行的命令。)
然后[SOME-STUFF]
部分由以下部分組成:
dir=${1%/*}
...使用參數擴展 ,將從$1
(文件名)的末尾刪除/*
的最短匹配,並將dir
設置為結果。 同樣,這部分:
base=${1##*/}
...從$1
的開頭刪除*/
的最長匹配,並將base
設置為結果。 所以base
只是路徑的最后一個組成部分。
然后重命名實際上是由mv
命令完成的,它是:
mv "$1" "$dir/${base//_/ }"
這再次使用參數擴展,這次使用${parameter/pattern/string}
語法。 的文件名( $1
)被重命名為$dir
隨后$base
但與每個強調在$base
與空間置換。
是的,只需cd到/ dir和:
find -depth -type d -execdir rename 's/_/ /g' {} \;
根據發行版,您需要perl重命名(有時是prename)。
如果
file $(type -p rename)
輸出包含ELF,看起來很糟糕;)
編輯 -depth和-execdir添加
如果你有bash4,你可以運行:
for i in **; do [[ -d "$i" ]] || continue; mv "$i" "${i/_/ }"; done
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.