J'essaie de pointer iconv vers un répertoire et tous les fichiers seront convertis en UTF-8 quel que soit l'encodage actuel
J'utilise ce script mais vous devez spécifier de quel encodage vous allez. Comment puis-je faire en sorte qu'il détecte automatiquement l'encodage actuel?
dir_iconv.sh
#!/bin/bash
ICONVBIN='/usr/bin/iconv' # path to iconv binary
if [ $# -lt 3 ]
then
echo "$0 dir from_charset to_charset"
exit
fi
for f in $1/*
do
if test -f $f
then
echo -e "\nConverting $f"
/bin/mv $f $f.old
$ICONVBIN -f $2 -t $3 $f.old > $f
else
echo -e "\nSkipping $f - not a regular file";
fi
done
ligne terminale
Sudo convert/dir_iconv.sh convert/books CURRENT_ENCODING utf8
Peut-être que vous recherchez enca
:
Enca est un analyseur de jeux de caractères extrêmement naïf. Il détecte le jeu de caractères et l'encodage des fichiers texte et peut également les convertir en d'autres encodages à l'aide d'un convertisseur intégré ou de bibliothèques et d'outils externes tels que libiconv, librecode ou cstocs.
Actuellement, il prend en charge le codage biélorusse, bulgare, croate, tchèque, estonien, hongrois, letton, lituanien, polonais, russe, slovaque, slovène, ukrainien, chinois et certains codages multi-octets indépendamment sur la langue.
Notez qu'en général, la détection automatique de l'encodage actuel est un processus difficile (la même séquence d'octets peut être un texte correct dans plusieurs encodages). enca
utilise une heuristique basée sur la langue que vous lui dites de détecter (pour limiter le nombre d'encodages). Vous pouvez utiliser enconv
pour convertir des fichiers texte en un seul encodage.
Vous pouvez obtenir ce dont vous avez besoin en utilisant le fichier utils gnu standard et awk. Exemple:
file -bi .xsession-errors
me donne: "text/plain; charset = us-ascii"
alors file -bi .xsession-errors |awk -F "=" '{print $2}'
me donne "us-ascii"
Je l'utilise dans des scripts comme ça:
CHARSET="$(file -bi "$i"|awk -F "=" '{print $2}')"
if [ "$CHARSET" != utf-8 ]; then
iconv -f "$CHARSET" -t utf8 "$i" -o outfile
fi
Les compiler tous. Allez dans dir, créez dir2utf8.sh:
#!/bin/bash
# converting all files in a dir to utf8
for f in *
do
if test -f $f then
echo -e "\nConverting $f"
CHARSET="$( file -bi "$f"|awk -F "=" '{print $2}')"
if [ "$CHARSET" != utf-8 ]; then
iconv -f "$CHARSET" -t utf8 "$f" -o "$f"
fi
else
echo -e "\nSkipping $f - it's a regular file";
fi
done
Voici ma solution pour placer tous les fichiers:
#!/bin/bash
apt-get -y install recode uchardet > /dev/null
find "$1" -type f | while read FFN # 'dir' should be changed...
do
encoding=$(uchardet "$FFN")
echo "$FFN: $encoding"
enc=`echo $encoding | sed 's#^x-mac-#mac#'`
set +x
recode $enc..UTF-8 "$FFN"
done
https://Gist.github.com/demofly/25f856a96c29b89baa32
mettre dans convert-dir-to-utf8.sh
et courir:
bash convert-dir-to-utf8.sh /pat/to/my/trash/dir
Notez que sed est une solution de contournement pour les encodages mac ici. De nombreux encodages peu courants nécessitent des solutions de contournement comme celle-ci.
Voici ma réponse ... = D
#!/bin/bash
find <YOUR_FOLDER_PATH> -name '*' -type f -exec grep -Iq . {} \; -print0 |
while IFS= read -r -d $'\0' LINE_FILE; do
CHARSET=$(uchardet $LINE_FILE)
echo "Converting ($CHARSET) $LINE_FILE"
# NOTE: Convert/reconvert to utf8. By Questor
iconv -f "$CHARSET" -t utf8 "$LINE_FILE" -o "$LINE_FILE"
# NOTE: Remove "BOM" if exists as it is unnecessary. By Questor
# [Refs.: https://stackoverflow.com/a/2223926/3223785 ,
# https://stackoverflow.com/a/45240995/3223785 ]
sed -i '1s/^\xEF\xBB\xBF//' "$LINE_FILE"
done
# [Refs.: https://justrocketscience.com/post/handle-encodings ,
# https://stackoverflow.com/a/9612232/3223785 ,
# https://stackoverflow.com/a/13659891/3223785 ]
QUESTION SUPPLÉMENTAIRE: Je ne sais pas si mon approche est la plus sûre. Je dis cela parce que j'ai remarqué que certains fichiers ne sont pas correctement convertis (les caractères seront perdus) ou sont "tronqués". Je soupçonne que cela a à voir avec l'outil "iconv" ou avec les informations de jeu de caractères obtenues avec l'outil "uchardet". J'étais curieux de connaître la solution présentée sur https://stackoverflow.com/a/22841847/3223785 (@demofly) car elle pourrait être plus sûre.
Une autre réponse, désormais basée sur la réponse de @demofly ...
#!/bin/bash
find <YOUR_FOLDER_PATH> -name '*' -type f -exec grep -Iq . {} \; -print0 |
while IFS= read -r -d $'\0' LINE_FILE; do
CHARSET=$(uchardet $LINE_FILE)
REENCSED=`echo $CHARSET | sed 's#^x-mac-#mac#'`
echo "\"$CHARSET\" \"$LINE_FILE\""
# NOTE: Convert/reconvert to utf8. By Questor
recode $REENCSED..UTF-8 "$LINE_FILE" 2> STDERR_OP 1> STDOUT_OP
STDERR_OP=$(cat STDERR_OP)
rm -f STDERR_OP
if [ -n "$STDERR_OP" ] ; then
# NOTE: Convert/reconvert to utf8. By Questor
iconv -f "$CHARSET" -t utf8 "$LINE_FILE" -o "$LINE_FILE" 2> STDERR_OP 1> STDOUT_OP
STDERR_OP=$(cat STDERR_OP)
rm -f STDERR_OP
fi
# NOTE: Remove "BOM" if exists as it is unnecessary. By Questor
# [Refs.: https://stackoverflow.com/a/2223926/3223785 ,
# https://stackoverflow.com/a/45240995/3223785 ]
sed -i '1s/^\xEF\xBB\xBF//' "$LINE_FILE"
if [ -n "$STDERR_OP" ] ; then
echo "ERROR: \"$STDERR_OP\""
fi
STDOUT_OP=$(cat STDOUT_OP)
rm -f STDOUT_OP
if [ -n "$STDOUT_OP" ] ; then
echo "RESULT: \"$STDOUT_OP\""
fi
done
# [Refs.: https://justrocketscience.com/post/handle-encodings ,
# https://stackoverflow.com/a/9612232/3223785 ,
# https://stackoverflow.com/a/13659891/3223785 ]
Solution hybride avec recode et vim ...
#!/bin/bash
find <YOUR_FOLDER_PATH> -name '*' -type f -exec grep -Iq . {} \; -print0 |
while IFS= read -r -d $'\0' LINE_FILE; do
CHARSET=$(uchardet $LINE_FILE)
REENCSED=`echo $CHARSET | sed 's#^x-mac-#mac#'`
echo "\"$CHARSET\" \"$LINE_FILE\""
# NOTE: Convert/reconvert to utf8. By Questor
recode $REENCSED..UTF-8 "$LINE_FILE" 2> STDERR_OP 1> STDOUT_OP
STDERR_OP=$(cat STDERR_OP)
rm -f STDERR_OP
if [ -n "$STDERR_OP" ] ; then
# NOTE: Convert/reconvert to utf8. By Questor
bash -c "</dev/tty vim -u NONE +\"set binary | set noeol | set nobomb | set encoding=utf-8 | set fileencoding=utf-8 | wq\" \"$LINE_FILE\""
else
# NOTE: Remove "BOM" if exists as it is unnecessary. By Questor
# [Refs.: https://stackoverflow.com/a/2223926/3223785 ,
# https://stackoverflow.com/a/45240995/3223785 ]
sed -i '1s/^\xEF\xBB\xBF//' "$LINE_FILE"
fi
done
REMARQUE: C'était la solution avec le plus grand nombre de conversions parfaites. De plus, nous n'avions aucun fichier tronqué.
AVERTISSEMENT: Faites une sauvegarde de vos fichiers et utilisez un outil de fusion pour vérifier/comparer les modifications. Des problèmes vont probablement apparaître!
CONSEIL: La commande sed -i '1s/^\xEF\xBB\xBF//' "$LINE_FILE"
peut être exécuté après une comparaison préliminaire avec l'outil de fusion après une conversion sans lui car il peut provoquer des "différences".
REMARQUE: La recherche utilisant "find" apporte tous les fichiers non binaires de "YOUR_FOLDER_PATH" et de ses sous-dossiers.
Merci!
Découvrez les outils disponibles pour une conversion de données dans une interface Linux: https://www.debian.org/doc/manuals/debian-reference/ch11.fr.html
De plus, il y a une quête pour trouver une liste complète des encodages disponibles dans iconv
. Exécutez simplement iconv --list
et découvrez que l'encodage des noms diffère des noms renvoyés par l'outil uchardet
(par exemple: x-mac-cyrillic dans uchardet
vs mac-cyrillic dans iconv
)
la commande enca ne fonctionne pas pour mon fichier texte en chinois simplifié avec codage GB2312.
Au lieu de cela, j'utilise la fonction suivante pour convertir le fichier texte pour moi. Vous pouvez bien sûr rediriger la sortie vers un fichier.
Il nécessite des commandes chardet et iconv.
detection_cat ()
{
DET_OUT=$(chardet $1);
ENC=$(echo $DET_OUT | sed "s|^.*: \(.*\) (confid.*$|\1|");
iconv -f $ENC $1
}