web-dev-qa-db-fra.com

Un moyen élégant de rechercher des fichiers UTF-8 avec BOM?

À des fins de débogage, je dois rechercher de manière récursive dans un répertoire tous les fichiers commençant par une marque d'ordre d'octet (BOM) UTF-8. Ma solution actuelle est un simple script Shell:

find -type f |
while read file
do
    if [ "`head -c 3 -- "$file"`" == $'\xef\xbb\xbf' ]
    then
        echo "found BOM in: $file"
    fi
done

Ou, si vous préférez des lignes simples et illisibles:

find -type f|while read file;do [ "`head -c3 -- "$file"`" == $'\xef\xbb\xbf' ] && echo "found BOM in: $file";done

Cela ne fonctionne pas avec les noms de fichiers qui contiennent un saut de ligne, .__, mais de tels fichiers sont inattendus.

Existe-t-il une solution plus courte ou plus élégante?

Existe-t-il des éditeurs de texte ou des macros intéressants pour les éditeurs de texte?

83
vog

Qu'en est-il de cette commande simple qui non seulement trouve, mais efface les noms désagréables? :)

find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;

J'aime "trouver" :)

Avertissement Ce qui précède modifier des fichiers binaires contenant ces trois caractères.

.

Si vous voulez seulement afficher les fichiers de nomenclature, utilisez celui-ci:

grep -rl $'\xEF\xBB\xBF' .
152
Denis

Le moyen le plus simple et le plus simple de le faire sous Windows:

Total Commander → aller au répertoire racine du projet → rechercher des fichiers (Alt + F7) → types de fichiers *. * → Rechercher du texte "EF BB BF" → cochez la case "Hex" → rechercher

Et vous obtenez la liste :)

39
Jan Przybylo
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

La plupart des solutions données ci-dessus testent plus que la première ligne du fichier, même si certaines (comme la solution de Marcus) filtrent ensuite les résultats. Cette solution teste uniquement la première ligne de chaque fichier, elle devrait donc être un peu plus rapide.

12
Aron Griffis

Si vous acceptez des faux positifs (s'il existe des fichiers non-texte ou, dans le cas peu probable, un ZWNBSP au milieu d'un fichier), vous pouvez utiliser grep:

fgrep -rl `echo -ne '\xef\xbb\xbf'` .
7
CesarB

Vous pouvez utiliser grep pour les trouver et Perl pour les éliminer comme suit:

grep -rl $'\xEF\xBB\xBF' . | xargs Perl -i -pe 's{\xEF\xBB\xBF}{}'
5
theory

Je voudrais utiliser quelque chose comme:

grep -orHbm1 "^`echo -ne '\xef\xbb\xbf'`" . | sed '/:0:/!d;s/:0:.*//'

Ce qui garantit que la nomenclature se produit à partir du premier octet du fichier.

5
Marcus Griep

Pour un utilisateur Windows, consultez this (bon script PHP permettant de trouver le BOM dans votre projet).

4
julien

Une solution excessive pour ceci est phptags (pas l'outil vi du même nom), qui recherche spécifiquement les scripts PHP:

phptags --warn ./

Produira quelque chose comme:

./invalid.php: TRAILING whitespace ("?>\n")
./invalid.php: UTF-8 BOM alone ("\xEF\xBB\xBF")

Et le mode --whitespace résoudra automatiquement ces problèmes (de manière récursive, mais affirme qu'il ne réécrit que les scripts .php.)

3
mario

J'ai utilisé cela pour corriger uniquement les fichiers JavaScript:

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
2
Refineo
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 met un null\0 entre chaque nom de fichier au lieu d'utiliser de nouvelles lignes
  • xargs -0 attend des arguments null séparés au lieu de séparer des lignes
  • grep -l liste les fichiers qui correspondent à la regex
  • La regex ^\xeff\xbb\xbf n'est pas tout à fait correcte, car elle correspond aux fichiers UTF-8 non-BOMed si leur largeur est zéro au début d'une ligne
2
Jonathan Wright

Si vous recherchez des fichiers UTF, la commande file fonctionne. Il vous dira quel est l'encodage du fichier. S'il y a des caractères non ASCII dedans, cela donnera UTF.

file *.php | grep UTF

Cela ne fonctionnera pas récursivement cependant. Vous pouvez probablement préparer une commande sophistiquée pour la rendre récursive, mais je viens de rechercher chaque niveau individuellement, comme ci-dessous, jusqu'à épuisement des niveaux.

file */*.php | grep UTF
0
Mike Dotterer