web-dev-qa-db-fra.com

Comment supprimer des caractères invalides des noms de fichiers?

J'ai des fichiers avec des caractères invalides comme ceux-ci

009_-_�%86ndringshåndtering.html

C'est un Æ où quelque chose s'est mal passé dans le nom du fichier.

Existe-t-il un moyen de supprimer simplement tous les caractères invalides?

ou tr pourrait-il être utilisé d'une manière ou d'une autre?

echo "009_-_�%86ndringshåndtering.html" | tr ???
50
Sandra

Une façon serait avec sed:

mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')

Remplacez file par votre nom de fichier, bien sûr. Cela remplacera tout ce qui n'est pas une lettre, un chiffre, un point, un trait de soulignement ou un tiret par un trait de soulignement. Vous pouvez ajouter ou supprimer des caractères à conserver comme vous le souhaitez et/ou remplacer le caractère de remplacement par autre chose, ou rien du tout.

44
James Sneeringer

Je suppose que vous êtes sur une boîte Linux et que les fichiers ont été créés sur une boîte Windows. Linux utilise UTF-8 comme encodage de caractères pour les noms de fichiers, tandis que Windows utilise autre chose. Je pense que c'est la cause du problème.

J'utiliserais "convmv". Il s'agit d'un outil qui peut convertir les noms de fichiers d'un codage de caractères à un autre. Pour l'Europe occidentale, l'un de ces travaux fonctionne normalement:

convmv -r -f windows-1252 -t UTF-8 .
convmv -r -f ISO-8859-1 -t UTF-8 .
convmv -r -f cp-850 -t UTF-8 .

Si vous devez l'installer sur un Linux basé sur Debian, vous pouvez le faire en exécutant:

Sudo apt-get install convmv

Cela fonctionne pour moi à chaque fois et il récupère le nom de fichier d'origine.

Source: LeaseWebLabs

32
mevdschee

J'ai eu des fichiers japonais avec des noms de fichiers cassés récupérés à partir d'une clé USB cassée et les solutions ci-dessus ne fonctionnaient pas pour moi.

Je recommande le forfait détox:

L'utilitaire de désintoxication renomme les fichiers pour les rendre plus faciles à utiliser. Il supprime les espaces et autres désagréments de ce type. Il traduira ou nettoiera également les caractères Latin-1 (ISO 8859-1) encodés en ASCII 8 bits, les caractères Unicode encodés en UTF-8 et les caractères d'échappement CGI.

Exemple d'utilisation:

detox -r -v /path/to/your/files
. .]
22
H. Hess

Je suppose que vous voulez dire que vous voulez traverser le système de fichiers et corriger tous ces fichiers?

Voici comment je le ferais

find /path/to/files -type f -print0 | \
Perl -n0e '$new = $_; if($new =~ s/[^[:ascii:]]/_/g) {
  print("Renaming $_ to $new\n"); rename($_, $new);
}'

Cela trouverait tous les fichiers avec des caractères non ascii et remplacerait ces caractères par des traits de soulignement (_). Soyez prudent cependant, si un fichier avec le nouveau nom existe déjà, il le remplacera. Le script peut être modifié pour vérifier un tel cas, mais je ne l'ai pas mis pour rester simple.

17
Patrick

Réponses suivantes sur https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-characters , vous pouvez utiliser:

rename 's/[^\x00-\x7F]//g' *

* correspond aux fichiers que vous souhaitez renommer. Si vous voulez le faire sur plusieurs répertoires, vous pouvez faire quelque chose comme:

find . -exec rename 's/[^\x00-\x7F]//g' "{}" \;

Vous pouvez utiliser l'argument -n pour rename pour effectuer un essai à blanc et voir ce qui serait modifié, sans le changer.

15
naught101

Ce script Shell assainit récursivement un répertoire, pour rendre les fichiers portables entre Linux/Windows et FAT/NTFS/exFAT. Il supprime les caractères de contrôle, /:*?"<>\| et certains noms Windows réservés comme COM0.

sanitize() {
  shopt -s extglob;

  filename=$(basename "$1")
  directory=$(dirname "$1")

  filename_clean=$(echo "$filename" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')

  if (test "$filename" != "$filename_clean")
  then
    mv -v "$1" "$directory/$filename_clean"
  fi
}

export -f sanitize

sanitize_dir() {
  find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
}

sanitize_dir '/path/to/somewhere'

Linux est moins restrictif en théorie (/ et \0 sont strictement interdits dans les noms de fichiers) mais en pratique plusieurs caractères interfèrent avec les commandes bash (comme *...) donc ils doivent également être évités dans les noms de fichiers.

Excellentes sources pour les restrictions de dénomination des fichiers:

5
KrisWebDev

Si vous souhaitez gérer les sauts de ligne, les caractères multi-octets, les espaces, les tirets, les barres obliques inverses et les espaces dont vous aurez besoin, quelque chose de plus robuste, voyez cette réponse:
https://superuser.com/a/858671/365691

Je mets le script sur code.google.com si quelqu'un est intéressé: r-n-f-bash-rename-script

1
A.Danischewski

J'utilise ce one-liner pour supprimer les caractères invalides dans les fichiers de sous-titres:

for f in *.srt; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.-]/./g;s/\.\.\././g;s/\.\././g'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done
  1. Traitez uniquement les fichiers * .srt (* peut être utilisé à la place de * .srt pour traiter chaque fichier)
  2. Supprime tous les autres caractères sauf les lettres A-Za-z, les chiffres 0-9, les points "." Et les tirets "-"
  3. Supprime les périodes doubles ou triples possibles
  4. Vérifie si le nom du fichier doit être modifié
  5. Si vrai, il renomme le fichier avec la commande mv, puis renvoie les modifications qu'il a apportées avec la commande echo

Cela fonctionne pour normaliser les noms de répertoire des films:

for f in */; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' -e 's/\.\.\././g' -e 's/\.\././g' -e 's/\.*$//'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done

Mêmes étapes que ci-dessus mais j'ai ajouté une commande sed supplémentaire pour supprimer un point à la fin du répertoire

X-Men Days of Future Past (2014) [1080p]
Modifié en:
X-Men.Days.of.Future.Past.2014.1080p

1
Brian Kuepper