find -execdir rename
也适用于基于文件名的非后缀替换。
https://dev59.com/WWQn5IYBdhLWcg3w1Z9f#16541670 直接适用于后缀,但对于任意正则表达式替换在文件名上都可以使用此方法:
PATH=/usr/bin find . -depth -execdir rename 's/_dbg.txt$/_.txt' '{}' \;
或仅对文件产生影响:
PATH=/usr/bin find . -type f -execdir rename 's/_dbg.txt$/_.txt' '{}' \;
-execdir
选项会首先进入目录,然后仅对基本名称执行操作。
在Ubuntu 20.04上测试过,适用于find 4.7.0和rename 1.10。
这是一个方便且更安全的帮助程序。
find-rename-regex() (
set -eu
find_and_replace="$1"
PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
find . -depth -execdir rename "${2:--n}" "s/${find_and_replace}" '{}' \;
)
GitHub上游。
示例用法,将空格“ ”替换为连字符“-”。
在不实际执行的情况下显示将被重命名为什么的干运行:
find-rename-regex ' /-/g'
做替换:
find-rename-regex ' /-/g' -v
命令说明
-execdir
这一神奇的选项在执行rename
命令之前会进入目录,与-exec
不同。
-depth
确保重命名首先发生在子级上,然后才是父级,以防止缺失父目录可能导致的问题。
需要使用-execdir
,因为rename
无法处理非基本名称的输入路径,例如以下操作会失败:
rename 's/findme/replaceme/g' acc/acc
由于
-execdir
具有一个非常令人讨厌的缺点,需要进行
PATH
破解:如果您的
PATH
环境变量中存在任何相对路径(例如
./node_modules/.bin
),则
find
会拒绝使用
-execdir
执行任何操作,并失败提示:
find:在PATH环境变量中包含相对路径“./node_modules/.bin”,这与find的-execdir操作组合在一起是不安全的。 请从$PATH中删除该条目。
另请参见:https://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378
-execdir
是GNU find的POSIX扩展。 rename
基于Perl并来自rename
软件包。
重命名前瞻解决方法
如果您的输入路径不来自find
,或者如果您已经受够了相对路径的烦恼,我们可以使用一些Perl前瞻来安全地重命名目录,如下所示:
git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'
我还没有找到与-execdir
和xargs
相匹配的方便工具: https://superuser.com/questions/893890/xargs-change-working-directory-to-file-path-before-executing/915686
sort -r
是必需的,以确保文件在它们各自目录的后面,因为较长的路径会在具有相同前缀的较短路径之后出现。
在Ubuntu 18.10中测试过。
Bareword "..." not allowed while "strict subs" in use at (eval 1) line 1.
的错误信息。 - Albert Hendriks