![使用特殊字符重命名文件和文件夹](https://linux22.com/image/985207/%E4%BD%BF%E7%94%A8%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6%E5%92%8C%E6%96%87%E4%BB%B6%E5%A4%B9.png)
对此我苦苦挣扎并在 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\n
和foo\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
如果这不能满足您的需要,请告诉我——还有其他使用非通配符的方法。