我有一些文件和文件夹保存在外部硬盘上的 Linux 中,其中一些文件和文件夹包含字符“::”,我想从驱动器上的所有文件和文件夹中删除这些字符,因为在 Windows 中尝试查看文件时遇到问题。
我已通过在终端中使用成功将它们从一个文件夹中删除 -
rename 's/:://' *::*.*
当在该单个目录中但想要对驱动器上的所有文件和文件夹执行此操作时,并且有许多子文件夹。
我可以向上述命令添加什么以使其对所有子文件夹和子文件夹中的文件起作用,或者是否有更好的命令。
谢谢。
答案1
您可以使用该find
命令递归搜索文件和目录,例如。
find path/to/start/dir/ -depth -name '*::*.*' -exec rename 's/:://' {} +
-depth
如果你要重命名文件,这一点很重要和目录(否则,该命令可能会在重命名某些匹配文件之前,通过重命名其包含的目录而使这些文件“孤立”)。如果您只希望重命名文件,则可以添加-type f
和删除-depth
.
我建议先运行该命令以rename -n
确保它执行正确的操作。
答案2
您可以尝试递归脚本。以下是一些可行的方法。这适用于我刚刚创建的测试目录,其中包含文件和目录,这些目录包含按您描述命名的文件。此脚本以递归方式遍历整个目录树,并将任何文件名中的任何 :: 替换为点。它设置为接受目录或目录列表作为参数,但它也可以用于单个文件。不确定这是否考虑到了所有需要考虑的事项或可能的错误情况,因此如果您使用它,请根据需要进行调整。
#!/bin/bash
function rmCols() {
if [[ ! -e $1 ]]
then
usage "$1" 1
fi
if [[ -f $1 ]]
then
if [[ -w $1 ]]
then
rename :: . "$1"
else
usage "$1" 2
fi
elif [[ -d $1 ]]
then
if [[ -w $1 ]]
then
for THING in "$1"/*
do
if [[ -f $THING ]]
then
rename :: . "$THING"
elif [[ -d $THING ]]
then
rmCols "$THING"
fi
done
else
usage "$1" 3
fi
else
usage "$1" 4
fi
}
function usage() {
echo "
Usage:
rmCols accepts a variable number of files and/or directories as arguments and will add the
current date between the filename and the file type extension for all files in all directory
argument(s) or for any file argument(s), recursively.
Syntax:
rmCols dirName_1 [dirName_2] [dirName_3] ......." >&2
if [[ $2 -eq 1 ]]
then
echo "
Error:
There is no such file or directory as $1, check your spelling" >&2
exit 1
elif [[ $2 -eq 2 ]]
then
echo "
Error:
You do not have permission to change the file $1" >&2
exit 2
elif [[ $2 -eq 3 ]]
then
echo "
Error:
You do not have permission to change the directory $1" >&2
exit 3
elif [[ $2 -eq 4 ]]
then
echo "
Error:
$1 is something other than a file or directory" >&2
exit 4
fi
}
shopt -s nullglob
for item in "$@"
do
[[ -h $item ]] && continue
rmCols "$item"
done
exit 0
这只会更改文件名而不是目录名,不过稍加修改应该也能处理目录名。可能有一个 Linux 工具可以在没有脚本的情况下完成此操作,但我不太熟悉。虽然这可行,但我相信有更好的解决方案。