我尝试从目录中的所有文件名中删除撇号。
for i in *; do mv $i `echo $i | tr -d "'"`; done
执行此命令后,没有任何内容被重命名。
你知道这里出了什么问题吗?
答案1
你可以尝试这样的事情(bash
):
shopt -s nullglob
for i in *\'* ; do mv -v "$i" "${i/\'/}" ; done
这使用 shell 字符串替换。您可能不想使用'
其中不包含的文件,因为这样mv
会失败。如果没有该选项,如果没有匹配的文件,nullglob
则将传递 glob 模式本身。mv
答案2
$foo
始终在变量替换和命令替换两边加上双引号$(foo)
(除非您知道为什么需要将它们排除在外以及为什么可以这样做)。
for i in *; do mv "$i" "$(echo "$i" | tr -d "'")"; done
这基本上可以工作,但有一些限制:
- 如果文件名以 开头
-
,您将得到不良行为或错误,因为mv
会将其解释为选项。 - 这不会影响名称以
.
. - 对于某些设置,这会破坏
echo
命令中的反斜杠。 - 名称末尾的换行符会丢失。
在 ksh93、bash 和 zsh 中,您可以使用该构造轻松编写此代码${VARIABLE//PATTERN/REPLACEMENT}
。添加--
到mv
会处理以-
.如果您的文件名以 开头.
,请根据需要在后面添加.*
或。.[^.]* ..?*
*
for i in *; do mv -- "$i" "${i//\'/}"; done
在 zsh 中,您可以使用zmv
:
zmv '(*)' "\${1//\\'/}"
在 Debian、Ubuntu 和其他衍生版本下,您可以使用rename
Perl 脚本。
rename "s/'//g" *
答案3
我认为您的问题是该文件的名称中也有空格。没有它我无法重现你的错误。
$ touch "file" "user's file"
$ for i in *; do mv $i `echo $i | tr -d "'"`; done
mv: `file1' and `file1' are the same file
mv: target `file' is not a directory
所以它失败的原因是第二条消息:target 'file' is not a directory
。
当您的 for 循环看到带有空格的文件时,它会运行以下命令:
mv user's file users file
因此它认为您指定了三个文件(user's
、file
和users
),以及一个将这些文件移动到的目录(file
)。
正确引用两者应该可以解决您眼前的问题
$ for i in ./*; do mv "$i" "$(echo "$i" | tr -d "'")"; done