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 ???
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.
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
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
. .]
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.
Réponses suivantes sur https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-characters , vous pouvez utiliser:
rename 's/[^\x00-\x7F]//g' *
où *
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.
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:
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
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
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