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

ItH*_*rtz 4 bash shell-script rename

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

find /path/to/folder -depth -name "* *" -execdir rename 's/ /-/g' "{}" \;
Run Code Online (Sandbox Code Playgroud)

它有效。

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

find /path/to/folder -depth -name "*.*" -execdir rename 's/./-/g' "{}" \;
Run Code Online (Sandbox Code Playgroud)

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

我究竟做错了什么?

cho*_*oba 12

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

\n
rename 's/\\./-/g'\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
's/(?<=.)\\./-/g'\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n
find /path/to/folder -depth -name '* *' -exec rename -d 's/\\./-/g' {} +\n
Run Code Online (Sandbox Code Playgroud)\n

如果您想保留最后一个点,可以使用前瞻断言来仅替换后面跟着一个点的点。

\n
's/(?<=.)\\.(?=.*\\.)/-/g'\n
Run Code Online (Sandbox Code Playgroud)\n
\n

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

\n

  • 在 unix 文件名中,没有_正式_的“扩展名”概念——它只是文件名中的字符。 (2认同)