使用特殊字符重命名文件和文件夹

使用特殊字符重命名文件和文件夹

对此我苦苦挣扎并在 Google 上搜索似乎并没有给我提供有效的解决方案。

我有一个名为...的文件夹

file å?? name.txt

例如,为了避免出现问题,我想重命名它,但是我不知道该怎么做。我尝试过使用' ',也尝试过\在每个特殊字符前使用,'file \å\?\? name \(2008\).txt'但只出现以下错误...

-bash: cd: file \å\?\? name \(2008\).txt : No such file or directory

这是不正确的使用方式吗\?或者我需要采用其他方法吗?

谢谢

答案1

非 ASCII 字符不是问题,您的 shell 可以å很好地处理。问题是您的文件实际上没有被命名为å??。如果是这样,rm 'å??'甚至rm å??会起作用。

你认为这是å??因为这就是所ls显示的,这是一个合理的假设,但ls会显示各种内容?。例如:

$ mkdir "file å"\?\?" name.txt" "file å"$'\n'$'\n'" name.txt" "file å"$'\t'$'\t'" name.txt" "file å"$'\r'$'\r'" name.txt" "file å"$'\b'$'\b'" name.txt" "file å"$'\v'$'\v'" name.txt"

$ ls -l
total 24K
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:01 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt

如上所示,换行符、制表符、回车符、铃声和垂直制表符(以及其他符号)均显示为?。 上面创建的文件/目录中,只有第一个文件/目录的?名称中才有 。 我们可以使用 来确认这一点ls -b

$ ls -lb
total 24
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å??\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\b\b\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\t\t\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:01 file\ å\n\n\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\v\v\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\r\r\ name.txt

因此,您可以运行ls -b以获取正确的文件名,然后使用ANSI C 引用重命名:

mv å$'\r'$'\r' newname

或者,你可以使用 glob 来匹配名称以file å(开头的所有文件/目录笔记:这仅在您只有一个时才有效):

mv "file å*" newname

或者,重命名名称中包含非字母数字字符的所有文件/目录(同样,仅适用于单一此类情况):

shopt -s extglob  ## turn on extended globbing
mv !(*([[:graph:]])) newname

奇怪的!(*([[:graph:]]))是需要解释一下。extglob启用扩展通配符,让我们使用它!(foo)来匹配“not foo”。[[:graph:]]字符类匹配所有可打印字符(不是制表符、换行符等)。因此,否定匹配!(*([[:graph:]]))将匹配所有带有非打印字符的文件/目录名。

如果你需要处理多个这样的情况,可以使用循环。例如:

for dir in !(*([[:graph:]])); do 
     mv "$dir" "${dir//[^[:graph:]]/_}"; 
done

${dir//[^[:graph:]]/_}目录名称,其中所有非打印字符均被 替换_。这种方法的问题是,您可以拥有不同的源目录,但这些目录最终会具有相同的名称(例如foo\nfoo\t都将变为foo_)。如果这是个问题,只需使用计数器重命名即可:

a=0; for dir in !(*([[:graph:]])); do 
    ((a++)); 
     mv "$dir" "${dir//[^[:graph:]]/_}$a"
done

这将导致:

drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt1
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt2
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt3
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å??_name.txt4
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt5
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt6

答案2

据我了解,您想使用终端重命名包含非英文字符的文件或文件夹。

为此,您可以使用

mv x y

其中 x 是您要重命名的文件/文件夹的名称,y 是您想要的新名称。

如果它有非英文字符和/或空格,那么使用 来' '指定 x 和 y 的限制就可以了。以下是一个例子:

mv 'öld namé öf fileş' 'néw namé öf fileş'

如果我误解了您的问题,请纠正我。

答案3

您显然已尝试转义和引用,您还可以使用带有烦人的文件名的通配符,例如,

$ ls *name\ 2008\ .txt    <==== make sure you only get the one file

$ mv *name\ 2008\ .txt  my_new_name.txt

如果这不能满足您的需要,请告诉我——还有其他使用非通配符的方法。

相关内容