关注此问题Recursively rename files using find and sed我自己找到了使用find重命名文件的解决方案,但我无法完全理解最后一部分
find . -name '*_test.rb' -exec bash -c 'echo mv $1 ${1/test.rb/spec.rb}' _ {} \;
任何人都可以解释字符“_ {}”的含义吗?我想这是从环境中映射的一些排序参数,但是......
欢迎提供一些澄清。
答案 0 :(得分: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 )传递给shell。
如果我们想要优化代码,只要我们的命令一次接受多个参数进行处理,我们就可以使用类似的东西:
% find . -type f -exec sh -c 'printf "arg -> %s\n" "$@"' {} +
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" "$@"' put_whatever_you_want_here {} +
arg -> ./file1
arg -> ./file2
arg -> ./file3
arg -> ./file4
arg -> ./file5
在某些情况下,您可能需要将 $ 0 设置为有意义的内容。