Command-Line

小寫一個目錄下的所有目錄

  • October 29, 2020

我想將目錄下的每個目錄的名稱小寫。我可以使用哪些命令來做到這一點?

一個級別的所有目錄,還是遞歸的?

Zsh

一方面:

autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'

遞歸:

zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'

說明:zmv根據給定的替換文本重命名匹配模式的文件。-o-i-i選項傳遞給幕後的每個mv命令(見下文)。在替換文本中$1$2、 等是模式中連續的括號組。**遞歸地表示所有(子)*目錄。final(/)不是帶括號的組,而是一個 glob 限定符,意思是只匹配目錄。${2:l}轉換$2為小寫。

便攜的

一方面:

for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done

final/將匹配限制為目錄,並mv -i在發生衝突時要求確認。刪除-i以在發生碰撞時覆蓋,然後使用yes n | for …. 不被提示並且不執行任何會發生衝突的重命名。

遞歸:

find root/* -depth -type d -exec sh -c '
   t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
   [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

使用-depth確保在其祖先之前處理深度嵌套的目錄。名稱處理依賴於/; 如果要在目前目錄中呼叫操作,請使用./*(調整 shell 腳本以應對.*留給讀者作為練習)。

Perl 重命名

在這裡,我使用 Debian 和 Ubuntu 提供的 Perl 重命名腳本/usr/bin/prename(通常rename也可用)。一方面:

rename 's!/([^/]*/?)$!\L/$1!' root/*/

遞歸地,使用 bash ≥4 或 zsh:

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' root/**/*/

遞歸地,可移植地:

find root -depth -type d -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +

引用自:https://unix.stackexchange.com/questions/5412