修復錯誤檔名的 shell 腳本?

修復錯誤檔名的 shell 腳本?

我是我的小公司的 IT 人員;而且,儘管我發出了可怕的警告,每個人都在伺服器上放置了帶有可怕名稱的文件,包括前導空格和尾隨空格、壞字元(包括\ ; / + . < > -等等!)

他們透過 Mac 上的 AFP 存取(FreeBSD/FreeNAS)伺服器來做到這一點,因此系統的任何部分都不會抱怨。

是否有一個腳本可以用來遍歷整個目錄樹並修復錯誤的檔案名稱?

基本上將所有空格和錯誤的 ASCII 替換為_...,如果檔案已經存在,只需_2在末尾添加 a 或其他內容即可。

我不認為有辦法讓系統執行好的文件命名約定,有嗎?

謝謝!

答案1

我會使用 bash 並查找。我確信有一個更簡單的選擇,但這就是我想出來的:

  1. 這樣可以處理包含「/」的檔案名稱(find會給予警告,忽略它),但是它只適用於目前目錄中的文件(沒有子目錄)。我不知道如何告訴 bash 或找到區分檔案名稱中的“/”和作為路徑一部分的“/”。

    for i in $(find . -maxdepth 1 -type f  -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" | sed 's/\.\///'); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}; done
    
  2. 這個不能處理包含“/”的文件名,但它將適用於當前目錄中的所有文件及其子目錄:

    for i in $(find . -type f  -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%]/_}; done
    

確保在運行之前測試這些。它們在我進行的幾次測試中運行良好,但我並不詳盡。也請記住,我使用的是 Linux 系統。 find 的特定實現(也許還有 bash)可能與您的不同。


編輯:將mv $i命令更改為“mv -i $i”將導致 mv 在覆蓋現有文件之前提示您。

EDIT2:要處理有空格的檔案名,您可以像這樣變更bash IFS(輸入欄位分隔符號)變數(改編自這裡):

SAVEIFS=$IFS; IFS=$(echo -en "\n\b"); for i in $(find . -type f  -name "*[\:\;\>\<\@\$\#\&\(\)\?\\\%\ ]*"); do mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\%\ ]/_}; done; IFS=$SAVEIFS

我還修改了正則表達式以下劃線匹配/替換空格。 SAVEIFS 位元只是將 IFS 變數傳回其原始配置。


解釋:

for i in $(command); do something $i; done

這是一個通用的 bash 循環。它將遍歷命令的輸出,依序將變數 $i 設定為命令傳回的每個值,並對它執行某些操作。


find . -maxdepth 1 -type f  -name "*[\:\;><\@\$\#\&\(\)\?\\\/\%]*" '

尋找目前目錄中名稱包含以下字元之一的所有檔案::;><@$#&()\/%.要添加更多內容,只需用“\”(例如“\¿”)轉義它們並將它們添加到方括號([ ])內的列表中。也許,並非所有這些字符都需要轉義,但我永遠記不起哪些是哪個環境中的特殊變量,所以我轉義了所有字符,以防萬一。

sed 's/\.\///

從 find 的輸出中刪除目前目錄,印出“foo”而不是“./foo”。

mv "$i" ${i//[\;><\@\$\#\&\(\)\?\\\/\%]/_}

每次這個小腳本循環時, $i 將是命名錯誤的檔案的名稱。此命令將移動(重新命名)該文件,將所有不需要的字元更改為“_”。尋找 bash 替換以獲取更多資訊。


相關內容