2011-10-16 113 views
1

在此之後questionn Recursively rename files using find and sed我發現自己這個解決方案使用find重命名文件,但我不能完全理解最後一部分使用bash重命名文件,命令澄清

find . -name '*_test.rb' -exec bash -c 'echo mv $1 ${1/test.rb/spec.rb}' _ {} \; 

任何人都可以解釋字義「 _ {}',?我想這是從環境映射的一些排序論據,但...

一些澄清將受到歡迎。

+0

您的報價不符。你能仔細檢查這是否是實際的命令嗎? – Thomas

+0

我認爲'* _test.rb'應該是'* _test.rb' – agtb

回答

1
-exec command ; 

字符串`{}'被替換爲正在處理的當前文件名。 考慮以下幾點:

% find . -type f 
./file1 
./file2 
./file3 
./file4 
./file5 
% find . -type f -exec sh -c 'printf "arg -> %s\n" "$0"' {} \; 
arg -> ./file1 
arg -> ./file2 
arg -> ./file3 
arg -> ./file4 
arg -> ./file5 

但在這裏我們執行sh -c ...對發現的每一個文件。 還請注意,文件名作爲$ 0(不是$ 1)傳遞給外殼。

如果我們wnat優化代碼,只要我們的命令在同一時間處理接受多個參數,我們可以用這樣的:

% find . -type f -exec sh -c 'printf "arg -> %s\n" "[email protected]"' {} + 
arg -> ./file2 
arg -> ./file3 
arg -> ./file4 
arg -> ./file5 

注意{} +語法(VS 。{} \;)。從找到手冊頁:

-exec command {} + 
      This variant of the -exec action runs the specified command on the selected files, but the command line 
      is built by appending each selected file name at the end; the total number of invocations of the com- 
      mand will be much less than the number of matched files. The command line is built in much the same 
      way that xargs builds its command lines. 

但是當你觀察,第一個文件丟失(因爲$ @包含了除$ 0的所有參數)。這就是爲什麼我們需要設置手工我們的$ 0時,爲了正確地處理所有的參數:

% find . -type f -exec sh -c 'printf "arg -> %s\n" "[email protected]"' put_whatever_you_want_here {} + 
arg -> ./file1 
arg -> ./file2 
arg -> ./file3 
arg -> ./file4 
arg -> ./file5 

在您可能需要設置$ 0爲有意義的一些情況。

+0

您可以擴展使用$ 1的原因,而不僅僅是'find。-name'* _test.rb'-exec bash -c'echo mv $ 0 $ {0/test.rb/spec.rb}'{} \;',please? – agtb

+0

嗨@agtb,對我來說沒有什麼區別_in this case_。如果你在調用執行的代碼裏面引用* $ 0 *的shell(* shell -c ... *),當然,你不會找到你所期望的... –