spc*_*s81 4 command-line special-characters filename rename
与这个斗争并在谷歌上搜索它似乎并没有给我提供有效的解决方案。
我有一个名为...的文件夹
file å?? name.txt
Run Code Online (Sandbox Code Playgroud)
例如,为了避免出现问题,我想重命名它,但是我正在努力弄清楚如何。我试过使用' ',我也试过\在每个特殊字符之前使用,例如,'file \å\?\? name \(2008\).txt'但我只是收到以下错误......
-bash: cd: file \å\?\? name \(2008\).txt : No such file or directory
Run Code Online (Sandbox Code Playgroud)
这是使用不当\还是我需要替代方法?
谢谢
非 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
Run Code Online (Sandbox Code Playgroud)
正如您在上面看到的,换行符、制表符、回车符、钟声和垂直制表符(以及其他)都显示为?. 只有上面创建的文件/目录中的第一个文件/目录实际上包含?在其名称中。我们可以通过以下方式确认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
Run Code Online (Sandbox Code Playgroud)
因此,您可以运行ls -b以获取正确的文件名,然后使用ANSI C 引用来重命名它:
mv å$'\r'$'\r' newname
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用 glob 来匹配名称以file å(注意:这仅在您只有一个时才有效)开头的所有文件/目录:
mv "file å*" newname
Run Code Online (Sandbox Code Playgroud)
或者,重命名名称包含非字母数字字符的所有文件/目录(同样,仅适用于您只有一个此类情况的情况):
shopt -s extglob ## turn on extended globbing
mv !(*([[:graph:]])) newname
Run Code Online (Sandbox Code Playgroud)
奇怪的!(*([[:graph:]]))需要一些解释。extglob启用扩展的通配符,让我们可以!(foo)用来匹配“not foo”。该[[:graph:]]字符类所有可打印字符(不制表符,换行符等)因此,否定匹配匹配!(*([[:graph:]]))将匹配与非打印字符的所有文件/ dirnames中。
如果您需要处理多个这样的情况,请使用循环。就像是:
for dir in !(*([[:graph:]])); do
mv "$dir" "${dir//[^[:graph:]]/_}";
done
Run Code Online (Sandbox Code Playgroud)
该${dir//[^[:graph:]]/_}是替换所有非打印字符的目录名_。这种方法的问题在于您可以拥有不同的源目录,它们最终会具有相同的名称(例如foo\n,foo\t都会变成foo_)。如果这是一个问题,也只需使用计数器重命名:
a=0; for dir in !(*([[:graph:]])); do
((a++));
mv "$dir" "${dir//[^[:graph:]]/_}$a"
done
Run Code Online (Sandbox Code Playgroud)
这将导致:
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
Run Code Online (Sandbox Code Playgroud)