递归地用连字符替换所有句点

递归地用连字符替换所有句点

要将所有文件/文件夹、所有子目录中的所有空格替换为连字符,我运行以下命令:

find /path/to/folder -depth -name "* *" -execdir rename 's/ /-/g' "{}" \;

它有效。

要将所有文件/文件夹、所有子目录中的所有句点(不包括扩展名)替换为连字符,我运行以下命令:

find /path/to/folder -depth -name "*.*" -execdir rename 's/./-/g' "{}" \;

但这不起作用。相反,它将文件名变成一长串 ------------

我究竟做错了什么?

答案1

句点在正则表达式中很特殊,它匹配任何字符。要按字面意思匹配句点,请反斜杠:

rename 's/\./-/g'

对于包括 GNU 在内的-execdir某些find实现find,每个名称都以句点开头。要跳过句点,请使用

's/(?<=.)\./-/g'

(?<=.)是一个后视断言检查句点之前是否有某些内容,但不会被替换。

某些 Perlrename变体还支持一个-d选项,使代码仅作用于文件的基本名称,然后您甚至不需要非标准的-execdir1:

find /path/to/folder -depth -name '* *' -exec rename -d 's/\./-/g' {} +

如果你想保留最后一个点,你可以使用前瞻断言仅替换某处后面有一个点的点。

's/(?<=.)\.(?=.*\.)/-/g'

1 这意味着您还可以使用+而不是;调用一个rename来处理多个文件。某些find实现也支持+-execdir但仍需要为每个包含其名称中rename的文件的目录至少运行一次。-

相关内容