J'ai ce projet PHP sur mon OSX, qui est en codage latin1. Maintenant, j'ai besoin de convertir des fichiers en UTF8. Je ne suis pas vraiment un codeur Shell et j'ai essayé quelque chose que j'ai trouvé sur Internet:
mkdir new
for a in `ls -R *`; do iconv -f iso-8859-1 -t utf-8 <"$a" >new/"$a" ; done
Mais cela ne crée pas la structure de répertoires et cela me charge énormément d'erreurs lors de l'exécution. Quelqu'un peut-il trouver une solution soignée?
Vous ne devriez pas utiliser ls
comme cela et une boucle for
n'est pas appropriée non plus. En outre, le répertoire de destination doit être en dehors du répertoire source.
mkdir /path/to/destination
find . -type f -exec iconv -f iso-8859-1 -t utf-8 "{}" -o /path/to/destination/"{}" \;
Pas besoin de boucle. L'option -type f
inclut les fichiers et exclut les répertoires.
Modifier:
La version iconv
de OS X ne possède pas l'option -o
. Essaye ça:
find . -type f -exec bash -c 'iconv -f iso-8859-1 -t utf-8 "{}" > /path/to/destination/"{}"' \;
Quelques bonnes réponses, mais j'ai trouvé cela beaucoup plus facile dans mon cas avec un répertoire imbriqué de centaines de fichiers à convertir:
$ vim $(find . -type f)
# in vim, go into command mode (:)
:set nomore
:bufdo set fileencoding=utf8 | w
Ceci convertit tous les fichiers avec l'extension .php
du nom de fichier - dans le répertoire actuel et ses sous-répertoires - en préservant la structure du répertoire:
find . -name "*.php" -exec sh -c "iconv -f ISO-8859-1 -t UTF-8 {} > {}.utf8" \; -exec mv "{}".utf8 "{}" \;
Remarques:
Pour obtenir une liste des fichiers qui seront ciblés au préalable, exécutez la commande sans les indicateurs -exec
(comme ceci: find . -name "*.php"
). Faire une sauvegarde est une bonne idée.
Utiliser sh
comme ceci permet de canaliser et de rediriger avec -exec, ce qui est nécessaire car toutes les versions de iconv ne prennent pas en charge l'indicateur -o
.
Ajouter .utf8
au nom de fichier de la sortie puis le supprimer peut sembler étrange, mais cela est nécessaire. L'utilisation du même nom pour les fichiers de sortie et d'entrée peut provoquer les problèmes suivants:
Pour les gros fichiers (environ 30 Ko selon mon expérience), cela provoque un vidage mémoire (ou termination by signal 7
)
Certaines versions de iconv semblent créer le fichier de sortie avant de lire le fichier d'entrée, ce qui signifie que si les fichiers d'entrée et de sortie ont le même nom, le fichier d'entrée est écrasé par un fichier vide avant sa lecture.
Pour convertir une arborescence de répertoires complète de l'iso-8859-1 à utf-8, y compris la création de sous-répertoires, aucune des solutions courtes ci-dessus ne fonctionnait pour moi car la structure de répertoires n'était pas créée dans la cible. Basé sur la réponse de Dennis Williamson, j'ai proposé la solution suivante:
find . -type f -exec bash -c 't="/tmp/dest"; mkdir -p "$t/`dirname {}`"; iconv -f iso-8859-1 -t utf-8 "{}" > "$t/{}"' \;
Il créera un clone de la sous-arborescence du répertoire en cours dans /tmp/dest
(à adapter selon vos besoins), y compris tous les sous-répertoires et avec tous les fichiers iso-8859-1
convertis en utf-8
. Testé sur macosx.
Btw: Vérifiez vos encodages de fichiers avec:
file -I file.php
pour obtenir les informations de codage.
J'espère que cela t'aides.
Je crée le script suivant qui (i) sauvegarde tous les fichiers tex du répertoire "converti", (ii) vérifie le codage de chaque fichier tex et (iii) convertit en UTF-8 uniquement les fichiers tex de l'ISO-8859-1 codage.
FILES=*.tex
for f in $FILES
do
filename="${f%.*}"
echo -n "$f"
#file -I $f
if file -I $f | grep -wq "iso-8859-1"
then
mkdir -p converted
cp $f ./converted
iconv -f ISO-8859-1 -t UTF-8 $f > "${filename}_utf8.tex"
mv "${filename}_utf8.tex" $f
echo ": CONVERTED TO UTF-8."
else
echo ": UTF-8 ALREADY."
fi
done
Si tous les fichiers que vous devez convertir sont des fichiers .php, vous pouvez utiliser les éléments suivants, qui sont récursifs par défaut:
for a in $(find . -name "*.php"); do iconv -f iso-8859-1 -t utf-8 <"$a" >new/"$a" ; done
Je crois que vos erreurs sont dues au fait que ls -R
génère également une sortie qui pourrait ne pas être reconnue par iconv comme un nom de fichier valide, quelque chose comme ./my/dir/structure:
.
Sur unix.stackexchange.com, une question similaire a été posée, et le manuel de l'utilisateur suggère de recoder ce qui fait très bien l'affaire.
Je l'utilise pour convertir ucs-2 en utf-8 en place
recode ucs-2..utf-8 *.txt
Utilisez mkdir -p "${a%/*}";
avant iconv.
Notez que vous utilisez une construction for
potentiellement dangereuse lorsqu'il existe des espaces dans les noms de fichiers, voir http://porkmail.org/era/unix/award.html .
En utilisant les réponses de Dennis Williamson et Alberto Zaccagni, j'ai développé le script suivant qui convertit tous les fichiers du type de fichier spécifié dans tous les sous-répertoires. La sortie est ensuite collectée dans un dossier donné par /path/to/destination
mkdir /path/to/destination
for a in $(find . -name "*.php");
do
filename=$(basename $a);
echo $filename
iconv -f iso-8859-1 -t utf-8 <"$a" >"/path/to/destination/$filename";
done
La fonction basename renvoie le nom du fichier sans le chemin du fichier.
Alternative (utilisateur interactif): .__ Maintenant, j'ai également créé un script utilisateur interactif qui vous permet de décider si vous souhaitez écraser les anciens fichiers ou simplement les renommer. Un merci supplémentaire à tbsalling
for a in $(find . -name "*.tex");
do
iconv -f iso-8859-1 -t utf-8 <"$a" >"$a".utf8 ;
done
echo "Should the original files be replaced (Y/N)?"
read replace
if [ "$replace" == "Y" ]; then
echo "Original files have been replaced."
for a in $(find . -name "*.tex.utf8");
do
file_no_suffix=$(basename -s .tex.utf8 "$a");
directory=$(dirname "$a");
mv "$a" "$directory"/"$file_no_suffix".tex;
done
else
echo "Original files have been converted and converted files were saved with suffix '.utf8'"
fi
Amusez-vous avec cela et je vous serais reconnaissant de tout commentaire pour l'améliorer, merci!
find . -iname "*.php" | xargs -I {} echo "iconv -f ISO-8859-1 -t UTF-8 \"{}\" > \"{}-utf8.php\""
Tout va bien avec les réponses ci-dessus, mais s’il s’agit d’un projet "mixte", c’est-à-dire qu’il existe déjà des fichiers UTF8, il est possible que nous ayons des problèmes. Voici donc ma solution.
#!/bin/bash
# file name: to_utf8
# current encoding:
encoding=$(file -i "$1" | sed "s/.*charset=\(.*\)$/\1/")
if [ "${encoding}" = "iso-8859-1" ] || [ "${encoding}" = "iso-8859-2" ];
then
echo "recoding from ${encoding} to UTF-8 file : $1"
recode ISO-8859-2..UTF-8 "$1"
fi
#example:
#find . -name "*.php" -exec to_utf8 {} \;