2017-01-09 85 views
1

我有一個文件系統,其中包含大量我想在Windows計算機上使用的文件。文件名中的非法字符是一個問題,所以我搜索了一個bash命令,遞歸地清理所有文件中的非法字符。用雙引號文件進行批量重命名

我發現這個解決方案(https://stackoverflow.com/a/19009177/7394134):

find . -name "*[<>:\\|?*]*" -exec bash -c 'x="{}"; y=$(sed "s/[<>:\\|?*]\+/-/g" <<< "$x") && mv "$x" "$y" ' \; 

它的工作對大多數文件,但它不包含雙引號的文件工作和失敗,出現以下錯誤信息:

bash :(其餘的文件名後雙引號):命令未找到

我發現有點不同的問題lik e「刪除含雙引號的文件」或「用文件中的sed刪除雙引號」,但不幸的是我無法將他們的解決方案轉移到上述命令的成功修改上。

備註:即使可能有一行更簡單(我很想看到它們!),我想通過-exec將文件名傳遞給由bash執行的三個命令。是否有可能創建一個命令,以這種方式刪除雙引號和單引號?

回答

0

一種方法是在bash中涉及command-substitution$(..)的所有操作進行適當的雙引號操作。如果不這樣做,shell會將執行的命令的結果(如果結果包含空格/特殊字符)作爲單獨的單詞處理。如果任何命令都對結果運行,錯誤很容易,因爲不正確的論點(在可能的情況,可能是由於可變y不正確賦值)

低於因此,一個簡單的技巧,雙引號的sed命令像,

find . -name "*[<>:\\|?*]*" -exec bash -c 'x="{}"; y="$(sed "s/[<>:\\|?*]\+/-/g" <<< "$x")" && mv "$x" "$y" ' \; 

可以爲你做的伎倆。

或者,如果你有興趣在一個更防呆的方式來處理與在名稱中包含特殊字符的文件,

GNU find使用-print0選項來處理文件名有特殊字符的文件/白的空間,與bashprocess-substitution。一個適當的腳本將

#!/bin/bash 

while IFS= read -r -d $'\0' file 
do 
    newfile="$(sed "s/[<>:\\|?*]\+/-/g" <<< "$file")" 
    mv -v -- "$file" "$newfile"  
done <(find . -name "*[<>:\\|?*]*" -print0) 

-print0 (a GNU find specific option)在每個文件/目錄find命令返回,以便處理與白色空間/特殊字符和read-d$'\0')名稱的末尾附加一個NULL角色,將來自輸出find以\ 0作爲解除限制器。