find -exec 中的子字符串删除

t-b*_*ltg 7 bash find

使用时

$ find . -name string~ -exec cp {} FOO \;
Run Code Online (Sandbox Code Playgroud)

有没有办法像我们通常使用 bash 子字符串那样使用{}inFOO删除波浪号字符

例如:

 $ echo ${string%substring}
Run Code Online (Sandbox Code Playgroud)

我的目标是将名为 string~ 的文件复制到 string(与 相反$ find . -name string -exec cp {} {}~ \;)。

Wil*_*ard 8

在这种情况下,您应该将代码执行填充到生成的 shell 中。

find . -name '*~' -exec sh -c 'cp "$0" "${0%~}"' {} \;
Run Code Online (Sandbox Code Playgroud)

这样您就不需要编写脚本。您只需在单行中完成即可。


注意:这里不需要--“选项结束”说明符cp,因为find将找到的文件前缀为./,这将防止它们被解析为cp.

(这个./前缀的例外是如果当前目录.本身是“找到”的,但当然该名称不会以波浪号结尾,也不会被误认为是选项标志。)


我什至会使用生成的 shell 在副本名称后附加波浪号;换句话说,我会使用:

find . -name string -exec sh -c 'cp "$1" "$1"~' find-sh {} \;
Run Code Online (Sandbox Code Playgroud)

优先于:

find . -name string -exec cp {} {}~ \;  # Don't use this!
Run Code Online (Sandbox Code Playgroud)

因为后者未由 POSIX 指定,因此不可移植。

来自POSIX 规范find

如果实用程序名称参数字符串包含两个字符“{}”,而不仅仅是两个字符“{}”,则find 是替换这两个字符还是不更改地使用字符串由实现定义。

... 如果存在多个包含两个字符“{}”的参数,则行为未指定。