Comment s’assurer que tous mes fichiers sources restnt UTF-8 avec les fins de ligne Unix?

Je recherche des outils en ligne de commande pour Linux qui peuvent m’aider à détecter et à convertir des fichiers de jeux de caractères tels que iso-8859-1 et windows-1252 en utf-8 et depuis des fins de ligne Windows vers des fins de ligne Unix.

La raison pour laquelle j’en ai besoin, c’est que je travaille sur des projets sur des serveurs Linux via SFTP avec des éditeurs sous Windows (comme Sublime Text) qui ne font que visser ces choses. En ce moment, je pense que la moitié de mes fichiers sont utf-8 , les autres sont iso-8859-1 et windows-1252, car il semble que Sublime Text sélectionne simplement le jeu de caractères par quels symboles le fichier contient quand je le sauvegarde. Les terminaisons de ligne sont TOUJOURS les fins de ligne Windows même si j’ai spécifié dans les options que les fins de ligne par défaut sont LF , donc environ la moitié de mes fichiers ont LF et la moitié sont CRLF .

J’aurais donc besoin d’au moins un outil pour parsingr de manière récursive mon dossier de projet et m’avertir des fichiers qui s’écartent d’ utf-8 avec les fins de ligne LF afin que je puisse les corriger manuellement avant de modifier mes modifications sur GIT.

Tous les commentaires et expériences personnelles sur le sujet seraient également les bienvenus.

Merci


Edit: J’ai une solution temporaire en place où j’utilise tree et file pour sortir des informations sur chaque fichier de mon projet, mais c’est plutôt compliqué. Si je n’inclue pas l’option -i pour le file beaucoup de mes fichiers obtiennent des résultats différents, comme le texte du programme ASCII C ++ et le texte du document HTML et du texte anglais, etc.:

 $ tree -f -i -a -I node_modules --noreport -n |  fichier xargs |  Répertoire grep -v
 ./config.json: texte du programme ASCII C ++
 ./debugserver.sh: texte ASCII
 ./.gitignore: texte ASCII sans terminaison de ligne
 ./lib/config.js: texte ASCII
 ./lib/database.js: texte ASCII
 ./lib/get_input.js: texte ASCII
 ./lib/models/stream.js: texte anglais ASCII
 ./lib/serverconfig.js: texte ASCII
 ./lib/server.js: texte ASCII
 ./package.json: texte ASCII
 ./public/index.html: texte du document HTML
 ./src/config.coffee: texte anglais ASCII
 ./src/database.coffee: texte anglais ASCII
 ./src/get_input.coffee: texte anglais ASCII avec terminateurs de ligne CRLF
 ./src/jtv.coffee: texte en anglais ASCII
 ./src/models/stream.coffee: texte en anglais ASCII
 ./src/server.coffee: texte ASCII
 ./src/serverconfig.coffee: texte ASCII
 ./testserver.sh: texte ASCII
 ./vendor/minify.json.js: texte de programme ASCII C ++, avec terminateurs de ligne CRLF

Mais si -i cela ne me montre pas les terminateurs de ligne:

 $ tree -f -i -a -I node_modules --noreport -n |  Fichier xargs -i |  Répertoire grep -v
 ./config.json: text / x-c ++;  charset = us-ascii
 ./debugserver.sh: text / plain;  charset = us-ascii
 ./.gitignore: text / plain;  charset = us-ascii
 ./lib/config.js: text / plain;  charset = us-ascii
 ./lib/database.js: text / plain;  charset = us-ascii
 ./lib/get_input.js: text / plain;  charset = us-ascii
 ./lib/models/stream.js: text / plain;  charset = us-ascii
 ./lib/serverconfig.js: text / plain;  charset = us-ascii
 ./lib/server.js: text / plain;  charset = us-ascii
 ./package.json: text / plain;  charset = us-ascii
 ./public/index.html: text / html;  charset = us-ascii
 ./src/config.coffee: text / plain;  charset = us-ascii
 ./src/database.coffee: text / plain;  charset = us-ascii
 ./src/get_input.coffee: text / plain;  charset = us-ascii
 ./src/jtv.coffee: text / plain;  charset = us-ascii
 ./src/models/stream.coffee: text / plain;  charset = us-ascii
 ./src/server.coffee: text / plain;  charset = us-ascii
 ./src/serverconfig.coffee: text / plain;  charset = us-ascii
 ./testserver.sh: text / plain;  charset = us-ascii
 ./vendor/minify.json.js: text / x-c ++;  charset = us-ascii

Aussi, pourquoi affiche-t-il charset = us-ascii et non utf-8 ? Et quel est le texte / x-c ++ ? Existe-t-il un moyen de ne sortir que charset=utf-8 et line-terminators=LF pour chaque fichier?

La solution avec laquelle je me suis retrouvé est les deux plugins Sublime Text 2 “EncodingHelper” et “LineEndings” . J’ai maintenant à la fois l’encodage des fichiers et les fins de ligne dans la barre d’état:

Sublime Text 2 barre d'état

Si le codage est erroné, je peux File-> Save with Encoding . Si les fins de ligne sont erronées, le dernier plug-in contient des commandes permettant de modifier les fins de ligne:

Sublime Text 2 commandes

Si un fichier n’a pas de nomenclature et qu’il n’ya pas de «caractères intéressants» dans la quantité de texte examinée par le file , le file conclut ASCII ISO-646 – un sous-ensemble ssortingct de UTF-8. Vous pourriez trouver que mettre des nomenclatures sur tous vos fichiers encourage tous ces outils Windows à se comporter; la convention d’une nomenclature sur un fichier UTF-8 provient de Windows. Ou cela pourrait empirer les choses. En ce qui concerne x / c ++, eh bien, cela ne fait que créer un file tryin ‘pour être utile, et échouer. Votre javascript contient quelque chose qui ressemble à C ++.

Apache Tika dispose d’un détecteur d’encodage; Vous pouvez même utiliser le pilote de ligne de commande qui l’accompagne comme alternative au file . Il va coller aux types MIME et ne pas se déplacer en C ++.

Au lieu de file , essayez un programme personnalisé pour vérifier uniquement les choses que vous voulez. Voici un rapide hack, principalement basé sur certains hits de Google, qui ont d’ailleurs été écrits par @ikegami.

 #!/usr/bin/perl use ssortingct; use warnings; use Encode qw( decode ); use vars (qw(@ARGV)); @ARGV > 0 or die "Usage: $0 files ...\n"; for my $filename (@ARGV) { my $terminator = 'CRLF'; my $charset = 'UTF-8'; local $/; undef $/; my $file; if (open (F, "<", $filename)) { $file = ; close F; # Don't print bogus data eg for directories unless (defined $file) { warn "$0: Skipping $filename: $!\n; next; } } else { warn "$0: Could not open $filename: $!\n"; next; } my $have_crlf = ($file =~ /\r\n/); my $have_cr = ($file =~ /\r(?!\n)/); my $have_lf = ($file =~ /(?!\r\n).\n/); my $sum = $have_crlf + $have_cr + $have_lf; if ($sum == 0) { $terminator = "no"; } elsif ($sum > 2) { $terminator = "mixed"; } elsif ($have_cr) { $terminator = "CR"; } elsif ($have_lf) { $terminator = "LF"; } $charset = 'ASCII' unless ($file =~ /[^\000-\177]/); $charset = 'unknown' unless eval { decode('UTF-8', $file, Encode::FB_CROAK); 1 }; print "$filename: charset $charset, $terminator line endings\n"; } 

Notez qu’il n’y a pas de concept de codage 8 bits hérité – il lancera simplement un fichier unknown si ce n’est pas du format ASCII 7 bits pur ou du format UTF-8 correct.