web-dev-qa-db-fra.com

Problème d'encodage des caractères avec les noms de fichiers - trouver les noms de fichiers cassés

J'ai le problème décrit dans ce Q & A . Probablement de vieilles distributions Linux ou de Windows, j'ai plusieurs fichiers avec des noms de fichiers cassés. ls affiche un "?" au lieu du personnage brisé. J'ai renommé avec succès certains de ces fichiers, mais je ne sais pas si je les ai tous trouvés.

Existe-t-il une méthode pour trouver tous les fichiers affectés?

5
lumbric

En supposant que vous utilisiez le codage utf-8 (la valeur par défaut dans Ubuntu), ce script devrait, espérons-le, identifier les noms de fichiers et les renommer à votre place.

Cela fonctionne en utilisant find avec le codage C (ascii) pour localiser les fichiers contenant des caractères non imprimables. Il essaie ensuite de déterminer si ces caractères non imprimables sont des caractères utf-8 ou non. Sinon, il vous montre les noms de fichiers décodés avec chacun des encodages listés dans le tableau enc, ce qui vous permet de sélectionner celui qui semble bon pour le renommer.

latin1 était couramment utilisé sur les anciens systèmes linux, et windows-1252 est couramment utilisé par les fenêtres aujourd'hui (je pense). iconv -l vous montrera une liste d'encodages possibles.

#!/bin/bash

# list of encodings to try. (max 10)
enc=( latin1 windows-1252 )

while IFS= read -rd '' file <&3; do
    base=${file##*/} dir=${file%/*}

    # if converting from utf8 to utf8 succeeds, we'll assume the filename is ok.
    iconv -f utf8 <<< "$base" >/dev/null 2>&1 && continue

    # display the filename converted from each enc to utf8
    printf 'In %s:\n' "$dir/"
    for i in "${!enc[@]}"; do
        name=$(iconv -f "${enc[i]}" <<< "$base")
        printf '%2d - %-12s: %s\n' "$i" "${enc[i]}" "$name"
    done
    printf ' s - Skip\n'

    while true; do
        read -p "? " -n1 ans
        printf '\n'
        if [[ $ans = [0-9] && ${enc[ans]} ]]; then
            name=$(iconv -f "${enc[ans]}" <<< "$base")
            mv -iv "$file" "$dir/$name"
            break
        Elif [[ $ans = [Ss] ]]; then
            break
        fi
    done
done 3< <(LC_ALL=C find . -depth -name "*[![:print:][:space:]]*" -print0)
10
geirha

Essaye ça:

find / | grep -P "[\x80-\xFF]"

Cela localisera tous les caractères non-ASCII dans les noms de fichiers et de dossiers et vous aidera à trouver les coupables: P

2
SirCharlo

Commencez avec cette commande regex find et modifiez-la jusqu'à ce que vous ne frappiez que ceux qui vous intéressent: find . | egrep [^a-zA-Z0-9_./-\s].
Celui ci-dessus trouvera les noms de fichiers qui ont un caractère non UTF-8.

1
yossile