web-dev-qa-db-fra.com

Impossible de supprimer / déplacer des fichiers avec des caractères spéciaux dans le nom de fichier

Comme vous pouvez le voir ci-dessous, les fichiers ont des caractères inhabituels.

file manager screenshot

Leur suppression dans le terminal ou Dolphin renvoie l'erreur:

Aucun fichier ou répertoire de ce nom

L'exécution de ls -la sur le répertoire m'a donné cette sortie:

-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

J'ai exécuté une commande fsck sur la partition à partir d'un autre système d'exploitation, mais cela n'a rien changé.

Comment puis-je supprimer ces fichiers?

17
karjedavpalaa

Un moyen simple serait de supprimer ces fichiers par leur inode. :)

Utilisez ls -li dans le répertoire avec les caractères inhabituels pour afficher le numéro d'inode de chaque fichier, par exemple,

$ 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????ą-??

Ensuite, utilisez l'utilitaire find pour supprimer le fichier correspondant par son nom, en utilisant la syntaxe find <somepath> -inum <inode_number> -exec rm -i {} \;, comme dans l'exemple suivant:

$ 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????ą-??

L'option -i de rm n'est pas vraiment nécessaire, je l'ai simplement ajoutée pour vous éviter de supprimer accidentellement des fichiers que vous ne vouliez pas supprimer. :) rm demande alors une confirmation de chaque fichier à supprimer.

Si vous souhaitez supprimer plusieurs fichiers à l'aide de leurs inodes, vous pouvez utiliser la syntaxe -o (signifiant o) pour 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

Vous pouvez ajouter plus de numéros d'inodes en étendant l'expression entre parenthèses avec plus d'expressions -o -inum <inode_number>.

35
Malte Skoruppa

Il est important de comprendre que ceci n'est pas le type de "corruption de système de fichiers" pour lequel fsckaidera. En ce qui concerne le système de fichiers, les noms de fichier peuvent être n’importe quelle séquence d’octets , tant qu’aucun octet n’a la valeur 0x00 (ASCII NUL, C marqueur de fin de chaîne) ou 0x2F (/, le séparateur de répertoire). (Si un nom de fichier intègre en quelque sorte un octet 00 ou 2F, fsckdevrait résoudre ce problème.)

Ce que vous avez, ce sont plutôt les noms de fichiers que le logiciel d’application (Dolphin, lsname__) contiennent des caractères qui sont non affichables dans votre "locale", les remplace par des caractères de substitution. Vous ne pouvez pas taper ces caractères non plus, il est donc plus difficile de manipuler les fichiers, mais vous pouvez le faire tant que vous le faites sans avoir à taper ou à copier. et coller le nom. Par exemple, si vous supprimez ou renommez les fichiers problématiques directement à partir de Dolphin, cela devrait fonctionner (j'irais même jusqu'à dire que si cela ne fonctionne pas, il s'agit d'un bogue dans Dolphin).

Si vous devez faire quelque chose à leur sujet à partir du Shell (par exemple, s’ils appartiennent à rootet qu’ils ne peuvent donc pas être modifiés par un programme graphique), vous pouvez les nommer indirectement à l’aide de modèles "glob", qui seront étendus au bon séquence (s) d'octets et transmis.

Maintenant, bien sûr, vous ne voudriez pas supprimer des éléments par accident, car votre modèle global correspond trop, je vous recommande donc d'utiliser l'utilitaire Perl renamepour convertir chaque nom de fichier en son codage hexadécimal:

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

Cela ne détruit aucune information - ni le fichier lui-même, ni le sens qui aurait pu être encodé à l'origine dans le nom du fichier avant qu'il ne soit mutilé. Il peut être annulé pour des fichiers spécifiques avec par exemple.

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

Attention: il existe deux programmes nommés renamename__, d’origines différentes; Les commandes ci-dessus ne fonctionneront qu'avec celles provenant de Perl. Dans Ubuntu, celui que vous voulez est celui du paquet "rename", pas celui du paquet "util-linux". rename -h distinguera: c'est ce que vous voulez ...

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

... Ce n'est pas ce que tu veux ...

$ rename -h

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

L'essentiel à rechercher est "perlexpr". Vous avez peut-être une ancienne version du nom renommé Perl qui ne comprend pas toutes les options ci-dessus, mais la commande que j'ai montrée devrait toujours fonctionner.

Edit: Sous 14.04 .5, le script Perl inclus pour renamene prend pas en charge le commutateur -h. Vous pouvez confirmer que vous avez le bon en consultant sa page de manuel avec man rename, auquel cas la ligne du haut contiendra:

RENAME (1) Guide de référence du programmeur Perl RENAME (1)

13
zwol