2012-10-18 57 views
9

我想遞歸地重命名所有包含字符串foo的目錄,方法是用代替的那部分字符串。到目前爲止,我已經有了類似的東西,但它並不奏效。我也想foo待檢索不區分大小寫在bash中遞歸重命名的目錄

find . -type d -exec bash -c 'mv "$1" "${1//foo/Bar}"' -- {} \;

是否有任何優雅的俏皮話,可能比這更好的嘗試?我其實已經嘗試了一些,但認爲我會推遲到專家。注意:我在Mac OS X系統上執行此操作,並且沒有安裝重命名等工具。

+0

你有沒有錯誤? –

+0

如果它是一次性計時器,它不需要是一個單行的:) – user1154664

回答

11

使用參數擴展

find . -type d -iname '*foo*' -depth -exec bash -c ' 
    echo mv "$1" "${1//[Ff][Oo][Oo]/BAr}" 
' -- {} \; 

嘗試下面的代碼,但你最好的選擇將是prename命令(有時名爲renamefile-rename

find . -type d -iname '*foo*' -depth -exec rename '[email protected]@[email protected]' {} + 

如果你正在使用bash4zsh**意思是遞歸):

shopt -s globstar 
rename -n '[email protected]@[email protected]' **/*foo*/ 

如果它符合您的需求,請刪除-n(空轉)開關重命名爲真實。

一些DOC

rename最初是由Perl的父親,拉里·沃爾親自寫的。

+2

奧術,醜陋和輝煌 –

+0

@sputnick - [如果你刪除了'sed'版本,我會很高興地注意到這個。]( http://mywiki.wooledge.org/ParsingLs):-) – ghoti

+0

添加'-depth'來處理subdir第一個 –

5
find . -type d -iname '*foo*' -exec bash -O nocasematch -c \ 
    '[[ $1 =~ (foo) ]] && mv "$1" "${1//${BASH_REMATCH[1]}/Bar}"' -- {} \; 

臨:避免了SED。
Con:如果在不同情況下有多個匹配項,則不會找到所有匹配項。
騙局:是荒謬的。

+0

OP需要不區分大小寫的替換。 –

+0

和'-name'不匹配「* FOO *」 –

+0

** + 1 ** - 編輯,這看起來像它會工作。是的,這有點荒謬。 :-) – ghoti

6

我懷疑問題是讓它與mkdir -p foo/foo/foo一起使用。

在這方面,我認爲基於find的解決方案可能無法工作,因爲路徑列表可能是預先確定的。

以下是絕不優雅和綿延一個班輪的定義,但適用於上述測試。

$ mkdir -p foo/foo/foo 

$ (shopt -s nullglob && _() { for P in "$1"*/; do Q="${P//[Ff][Oo][Oo]/bar}"; mv -- "$P" "$Q"; _ "$Q"; done } && _ ./) 

$ find 
. 
./bar 
./bar/bar 
./bar/bar/bar 
+0

** + 1 ** - 優秀點。奧術使用bash。工作很好。 :) – ghoti

0

我一直在尋找類似的答案,這一次的工作:

find . -depth -name 'foo' -execdir bash -c 'mv "$0" ${0//foo/Bar}"' {} \;