如何遞歸更改bash下文件和文件夾的大小寫
我有一些文件和文件夾都是大寫的,我想將它們重命名為對應的小寫字母。在 Linux 系統上用 bash 執行此操作的最佳方法是什麼?
例如,我可能有:
. |-- FOLDER0 | |-- SUBFOLDERA | `-- SUBFOLDERB `-- FOLDER1 `-- AFILE.TXT
我想將其轉換為:
. |-- folder0 | |-- subfoldera | `-- subfolderb `-- folder1 `-- afile.txt
我可能可以編寫一個深度優先遞歸腳本來執行此操作(深度優先以確保文件和子文件夾在其父文件夾之前重命名),但我想知道是否有更好的方法。
rename
可能有用,但它似乎不支持遞歸。
find . -depth -print0 | xargs -0 rename -n '$_ = lc $_'
一旦您確定它正在執行您想要的操作,請取出 -n 標誌。
這更像是對該論壇工作方式的評論和元觀察,但我強烈認為應該比我只是在 rudedog 的回答中發表評論更大聲地說明它。這也是一個評論,更多地針對那些可能有與大衛迪恩的問題相似但不完全相同的問題的人。
重命名文件的遞歸操作很容易造成大量損壞。讓我再說一遍,因為它非常重要。您可以使用重命名文件的遞歸操作非常非常快速地銷毀大量數據。您可以快速使系統完全無法使用。您可以非常快速地刪除 99% 的數據。這樣的操作應該非常小心地完成,並且需要大量的思考、備份和測試執行。
對於這個具體問題的答案,我非常謹慎,因為它依賴於幾個具體的隱含假設:
- 我使用的“重命名”版本與您使用的版本相同,並且它們都具有我習慣的安全功能。據我所知,“重命名”在 unix 中不是一些標準的、正常的實用程序。它似乎是某些發行版中存在的一些聰明的腳本。
- 所描述的“重命名”具有一些防止覆蓋文件的安全功能。
- 被修改的文件要麼具有明確的壓縮大小寫結果,要麼如果生成的子目錄有一些大寫文件,因為壓縮大小寫結果發生衝突並且名稱更改機制不執行任何操作目標名稱已經存在。
我對做捷徑的事情感到非常自在。然而,我試圖理解某些東西是捷徑以及這種捷徑的局限性是什麼,以便我知道何時需要執行始終正確的程序或快 10,000 倍但在某些邊緣情況下失敗的捷徑。
簡而言之——上述使用重命名的腳本在 90% 的情況下是 100% 合理的。在 100% 的情況下 100% 正確的解決方案實際上有點複雜,並且在處理命名空間衝突時需要一些技巧。
但是,正如我之前所說,對遞歸文件操作要非常小心,尤其是當它們只處理諸如權限或文件名之類的元數據時。如果不進行備份,它們會快速且難以逆轉…
這是一個如何在 bash 或 ksh 或其他具有“排版”的現代 shell 中編寫“重命名”命令的範例。讓我們將此腳本稱為 /tmp/squash
#!/usr/local/bin/pdksh # use some shell that supports typeset such as ksh, pdksh, or bash # call this script from "xargs -0" and feed it with "find -print0" typeset -l targetname || { echo "This shell doesn't support typeset!" >&2 ; exit 1 ; } for file do count="" target="$file" targetpath="${target%/*}/" targetname="${target##*/}" if [[ "$file" == "$targetpath$targetname" ]] || [[ "$file" == . ]] then : else while test -e "$targetpath/$targetname""$count" do count=$((${count:-0}+1)) done echo "renaming $file to $targetpath$targetname$count" >&2 mv -n "$file" "$targetpath$targetname$count" fi done
現在,您可以執行以下兩個命令,將文件全部壓縮,並且不會覆蓋任何文件。
find /path/to/files -type f -print0 | xargs -0 /tmp/squash find /path/to/files -type d -depth -print0 | xargs -0 /tmp/squash
而且我假設有問題的目錄在我執行程序時不會放入任何東西或重命名的東西。