Os caracteres não-ASCII não são o problema, seu shell pode lidar com å
perfeitamente bem. A questão é que seu arquivo não é realmente chamado de å??
. Se fosse, rm 'å??'
ou mesmo rm å??
teria funcionado.
Você assume que é å??
porque é isso que ls
mostra, e essa é uma suposição razoável, mas ls
mostrará várias coisas como ?
. Por exemplo:
$ 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
Como você pode ver acima, novas linhas, tabulações, retornos de carro, sinos e tabulações verticais (entre outros) são todos mostrados como ?
. Somente o primeiro arquivo / diretório daqueles criados acima tem ?
em seu nome. Podemos confirmar isso com 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
Assim, você pode executar ls -b
para obter o nome de arquivo correto e, em seguida, usar ANSI C citando para renomeá-lo:
mv å$'\r'$'\r' newname
Como alternativa, você pode usar um glob para corresponder a todos os arquivos / diretórios cujo nome comece com file å
( nota: isso só funcionará se você tiver apenas um):
mv "file å*" newname
Ou renomeie todos os arquivos / diretórios cujo nome contenha caracteres não alfanuméricos (novamente, útil somente para casos em que você tenha um único caso):
shopt -s extglob ## turn on extended globbing
mv !(*([[:graph:]])) newname
O estranho !(*([[:graph:]]))
precisa de alguma explicação. extglob
ativa a globalização estendida, o que nos permite usar !(foo)
para corresponder a "não foo". A classe de caracter [[:graph:]]
corresponde a todos os caracteres imprimíveis (não a guias, novas linhas, etc.) Portanto, a correspondência negada !(*([[:graph:]]))
corresponderá a todos os arquivos / dirnames com caracteres não imprimíveis.
Se você precisar lidar com mais de um caso, use um loop. Algo como:
for dir in !(*([[:graph:]])); do
mv "$dir" "${dir//[^[:graph:]]/_}";
done
O ${dir//[^[:graph:]]/_}
é o nome do diretório com todos os caracteres não imprimíveis substituídos por _
. O problema com essa abordagem é que você pode ter diferentes diretórios de origem que acabarão com o mesmo nome (por exemplo, foo\n
e foo\t
se tornarão foo_
). Se isso for um problema, basta renomear usando um contador também:
a=0; for dir in !(*([[:graph:]])); do
((a++));
mv "$dir" "${dir//[^[:graph:]]/_}$a"
done
Isso resultaria em:
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