No se pueden eliminar / mover archivos con caracteres especiales en el nombre del archivo

17

Como puede ver a continuación, los archivos tienen caracteres poco comunes.

captura de pantalla del administrador de archivos

Eliminarlos en la terminal o Dolphin devuelve el error:

El fichero o directorio no existe

Ejecutar ls -laen el directorio me dio esta salida:

-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ?2?.???љ?!?Gb??σ?[?F?
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 3l??#g?w????O?JKB7?co??քH??bT?NA???S???X?I?A?qC??M?I???
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??8??-?@,?Zp?[?bI????7^?ñ[?ڏ??z?O???ч??eEȰ?+??,OF??h

Ejecuté un fsckcomando en la partición desde otro sistema operativo pero no cambió nada.

¿Cómo elimino estos archivos?

karjedavpalaa
fuente
1
¿Configuraste tu sistema para tener un directorio de inicio encriptado?
dobey
@dobey no lo hice.
karjedavpalaa
55
@Panther Estás equivocado. Esto no es , en sí mismo, una indicación de un sistema de archivos corrupto, e incluso si fue causado por algún tipo de corrupción de datos, fsck no hará nada al respecto.
zwol
1
He tenido archivos con caracteres no reconocidos en el nombre. Cambiar el nombre de los archivos funcionó. entonces podrían ser eliminados.
ravery

Respuestas:

35

Una forma simple sería eliminar estos archivos por su inodo. :)

Use ls -lien el directorio con los caracteres poco comunes para mostrar el número de inodo de cada archivo, por ejemplo,

$ ls -li
total 0
133370 -rw-r--r-- 1 malte malte 0 Dec 30 19:00 ?2?.???љ?!?Gb??σ?[?F?
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

Luego, use la findutilidad para eliminar el archivo correspondiente por su nombre, usando la sintaxis find <somepath> -inum <inode_number> -exec rm -i {} \;, como en el siguiente ejemplo:

$ find . -inum 133370 -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
$ ls -li
total 0
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

La -iopción rmno es realmente necesaria, solo la agregué para evitar que elimines accidentalmente archivos que no querías eliminar. :) Hace rmque se solicite confirmación para cada archivo que desea eliminar.

Si desea eliminar varios archivos por sus inodos, puede usar la sintaxis -o(significado o ) para find:

$ find .  \( -inum 133370 -o -inum 132584 \) -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
rm: remove regular empty file ‘./??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??’? y

Puede agregar más números de inodo extendiendo la expresión entre paréntesis con más -o -inum <inode_number>expresiones.

Malte Skoruppa
fuente
44
¿Qué tal rm -ri .?
Brent Baccala
Esto funcionó: find <somepath> -inum <inode_number> -exec rm -i {} \; ¿Qué hacen '-inum', '{}' y '\' en el comando?
karjedavpalaa
¿Cómo elimino varios archivos de una vez? Además, gracias, ¡me alegraste el día!
karjedavpalaa
2
Sin embargo, @BrentBaccala rm -ri .no está eliminando archivos por inodo. Simplemente se repetirá a través de todo el directorio de trabajo y solicitará cada archivo si desea eliminarlo, y debe estar muy atento a qué archivos está solicitando para no eliminar accidentalmente los no deseados. Ciertamente no me gustaría usar este comando para mi directorio de inicio, ya que contiene MUCHOS archivos. ;)
Malte Skoruppa
3
@karjedavpalaa (1) -inumle dice findque busque archivos por su número de inodo. (2) {}coincide con los archivos encontrados por grep. (3) \ escapa al ;símbolo que termina el comando pasado a la -execopción de find. (4) He editado mi respuesta para explicar cómo eliminar varios archivos de una vez.
Malte Skoruppa
13

Es importante comprender que este no es el tipo de "corrupción del sistema de archivos" que fsckayudará. En lo que respecta al sistema de archivos, los nombres de archivo pueden ser cualquier secuencia de bytes , siempre que ningún byte tenga el valor 0x00 (ASCII NUL, marcador de fin de cadena C) o 0x2F ( /, el separador de directorio). (Si un nombre de archivo de alguna manera obtiene un byte 00 o 2F incrustado en él, fsckdebería solucionarlo).

Más bien, lo que tiene son nombres de archivos que el software de la aplicación (Dolphin ls) cree que contienen caracteres que no se pueden mostrar en su "ubicación", por lo que los reemplaza con caracteres de marcador de posición. Tampoco puede escribir esos caracteres, por lo que manipular los archivos es más difícil, pero puede hacerlo siempre que lo haga sin tener que escribir o copiar y pegar el nombre. Por ejemplo, si elimina o cambia el nombre de los archivos del problema directamente desde Dolphin, eso debería funcionar (diría que si no funciona, eso es un error en Dolphin).

Si necesita hacer algo al respecto desde el shell (por ejemplo, si son propiedad de rootun programa GUI y, por lo tanto, no pueden ser modificados), puede nombrarlos indirectamente utilizando patrones "glob", que se expandirán a la secuencia correcta (s) de bytes y transmitidos.

Ahora, por supuesto, no querrás eliminar cosas por accidente porque tu patrón global coincide demasiado, por lo que mi recomendación sería usar la renameutilidad Perl para convertir cada nombre de archivo a su codificación hexadecimal:

$ rename '$_ = unpack("H*", $_)' *

Esto no destruye ninguna información, ni el archivo en sí mismo, ni el significado que originalmente se haya codificado en el nombre de archivo antes de que fuera destruido. Se puede deshacer para archivos específicos con, por ejemplo,

$ rename '$_ = pack("H*", $_)' 696d706f7274616e742e646f63

Precaución: hay dos programas nombrados rename, de diferentes orígenes; los comandos anteriores solo funcionarán con el que se originó con Perl. En Ubuntu, el que desea es el del paquete "rename", no el del paquete "util-linux". rename -hdistinguirá: esto es lo que quieres ...

$ rename -h
Usage:
    rename [ -h|-m|-V ] [ -v ] [ -n ] [ -f ] [ -e|-E perlexpr]*|perlexpr
    [ files ]
# ...

... Esto no es lo que quieres ...

$ rename -h

Usage:
 rename [options] <expression> <replacement> <file>...
# ...

La clave para buscar es "perlexpr". Es posible que tenga una versión anterior del cambio de nombre de Perl que no comprende todas las opciones anteriores, pero el comando que mostré debería funcionar.

Editar: en 14.04 .5, el script perl que se incluye renameno admite el modificador -h. Puede confirmar que tiene la correcta marcando su página de manual, man renameen cuyo caso la línea superior contendrá:

RENAME (1) Guía de referencia de programadores de Perl RENAME (1)

zwol
fuente
renombrar --version Opción desconocida: versión
Elder Geek
@ElderGeek ¿Qué file $(which rename)imprime? (Asegúrese de tener el filepaquete instalado, primero.)
zwol
/usr/bin/rename: symbolic link to /etc/alternatives/rename( fileestá instalado de forma predeterminada) En realidad, debe perseguir los enlaces simbólicos para obtener, /usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable pero man renamees una indicación más rápida ...
Elder Geek
@ElderGeek Si es un script perl, entonces es probable que sea una versión anterior del "uno que se originó con Perl", que no es compatible --version; el comando que sugerí aún debería funcionar. (/usr/share/doc/rename/changelog.gz en mi computadora, que ejecuta Debian inestable, indica que --versionse agregó en la versión 0.10 del cambio de nombre de Perl, en 2013. Me sorprende que Ubuntu todavía envíe algo más antiguo que eso, pero este programa no ha cambiado su funcionalidad desde 2007 (!) así que está bien.)
zwol
Ah! Eso explica la confusión. A pesar de muchas afirmaciones de lo contrario, Debian no es Ubuntu. No puedo hablar para cada lanzamiento, pero algunas versiones actualmente compatibles de Ubuntu LTS (14.04) todavía no tienen eso. (Aunque 16.04 sí lo hace)
Elder Geek