使用 bash 重命名文件,命令说明

发布于 2024-12-10 14:16:20 字数 367 浏览 0 评论 0原文

遵循这个问题使用find和sed递归重命名文件我自己找到了这个使用 find 重命名文件的解决方案,但我无法完全理解最后一部分

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

任何人都可以解释字符 '_ {}', 的含义吗?我想这是从环境映射的某种参数,但是......

欢迎一些澄清。

Following this questionn Recursively rename files using find and sed I found by myself this solution to rename files using find, but I can not fully understand the last part

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

Can anyone explain the meaning of characters '_ {}',? I guess that is some sort arguments mapping from enviroments, but ...

Some clarification will be welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落在眉间の轻吻 2024-12-17 14:16:20
-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

注意 {} + 语法(相对于 {} \;)。从找到手册页:

-exec 命令 {} +
          -exec 操作的此变体对所选文件运行指定的命令,但命令行
          通过在末尾附加每个选定的文件名来构建;该com的调用总数
          mand 将远小于匹配文件的数量。命令行的构建方式大致相同
          xargs 构建命令行的方式。

但正如您所观察到的,第一个文件丢失了(因为 $@ 包含除 $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 设置为有意义的值。

-exec command ;

The string `{}' is replaced by the current file name being processed.
Consider the following:

% 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

But here we execute sh -c ... for every single file found.
Note also that the filename is passed to the shell as $0 (not $1).

If we wnat to optimize the code, as long as our command accepts more than one argument at a time for processing, we could use something like this:

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

Note the {} + syntax (vs. {} \;). From find man pages:

-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.

But as you observe, the first file is missing (because $@ contains all parameters except $0). That's why we need to set our $0 by hand, in order to process all arguments correctly:

% 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

In some situations you may need to set $0 to something meaningful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文