如何使用`rename`递归删除所有文件中的所有单引号?

标题已经说得很清楚了,我知道有很多类似的问题,但最接近的我找到的是删除“而不是'。到目前为止,我尝试过的方法有:
find -name "*'*" -type f | rename 's/\'//g'

或者使用rename 's/[']//g'和其他一些变体。 我找到了所有的文件,但是当我将它管道传输到rename时,我只能得到一个提示符>,然后不得不按下Ctrl+C键返回。最近我使用这个方法成功地改变了许多文件中的特殊字符,除了单引号之外。
2个回答

你可以使用双引号:" "。
rename -n "s/'//g"

在测试后移除-n,以便真正重命名文件

不过要使用-exec...

find -name "*'*" -type f -exec rename -n "s/'//g" '{}' \;

如果列表不太长,请加快速度...

find -name "*'*" -type f -exec rename -n "s/'//g" '{}' +

或者,如评论中建议的那样,使用递归的 shell globbing:

shopt -s globstar
rename -n "s/'//g" **/*"'"*

你可以使用shopt -u globstar来关闭递归通配符**,但当你启动一个新的shell时,它将自动关闭。

rename 命令有自己的文件通配符语法,所以这里可能不需要使用 find 命令。 - Tom Russell
@TomRussell哦,真的吗?我不知道这个 - 我使用shell与rename进行通配(这里可能会有globstar)。你愿意发表一个回答来演示一下吗? - Zanna
最后一个参数是标准的shell globbing: 用法: rename [选项] <表达式> <替换> <文件>... - Tom Russell
哎呀,我忽略了考虑到原帖问题的递归方面。 - Tom Russell
@TomRussell,那个输出看起来像是来自另一个rename命令(rename.ul)的结果。我对那个命令不太熟悉,但我没有找到关于rename自己的通配符语法(就像find一样)的任何信息。Bash有globstar可以使**递归生效,但需要再次引用单引号...在Bash 5.0.17中,shopt -s globstar; rename -n "s/'//g" **/*"'"*对我有效。 - Zanna
酷东西。我的shell技术还不太行。:-) - Tom Russell
@TomRussell 谢谢你指出了一个无需查找的版本。我已经将它添加到答案中 :) - Zanna
很贴心地告诉了如何关闭globstar。那你是在使用bash吗?我得到了“rename: 参数不足”的错误提示。 - Tom Russell
这在我的系统上有效:$ rename "'" '' **。这里的三个参数分别是:"'"''**,告诉rename命令将引号替换为空字符串,并且递归地执行此操作。 - Tom Russell
@TomRussell,那是另一个具有不同语法的重命名命令。这个问题是关于perl重命名命令的。我对另一个命令不熟悉。是的,使用Bash。我不知道其他shell是否支持globstar。 - Zanna
正确。这是关于bash内置命令的问题。我在问题中没有看到提到Perl。 - Tom Russell
@TomRussell 我的Bash没有rename内置命令,根据type -a显示。我称之为rename Perl rename,因为它是一个Perl脚本并且使用Perl表达式。在Ubuntu中,它要么默认安装,要么可以从rename软件包中获取。另一个rename来自util-linux软件包,在Ubuntu上我们需要使用rename.ul来避免混淆。OP命令的语法以及他们在Ubuntu上调用的是rename而不是rename.ul,强烈暗示他们所说的rename是指Perl版本(尽管你的回答可能对其他人有帮助)。 - Zanna
嘿,真让我吃惊! :-) 我对Ubuntu不太熟悉,但没想到bash shell之间会有这么大的差异。我很好奇这种差异的原因是什么。我得推测一下,也许Perl命令是对shell二进制文件更强大的封装。 - Tom Russell

这在我的系统(OpenSUSE Leap)上可以使用bash运行:
$ rename "'" '' **
rename函数的三个参数是:"'"''**globstar),这要告诉它将引号替换为空字符串,并且要递归地这样做。
请注意,**globstar)在我的系统上默认是开启的。我不知道有没有关闭它的方法。