2008-10-15 2 views
78

Pour le débogage, j'ai besoin de rechercher récursivement un répertoire pour tous les fichiers qui commencent par une marque d'ordre d'octet (BOM) UTF-8. Ma solution actuelle est un simple script shell:Une manière élégante de rechercher des fichiers UTF-8 avec BOM?

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 court, illisibles one-liners:

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

Il ne fonctionne pas avec les noms de fichiers contenant un saut de ligne, mais de tels fichiers ne sont pas attendus de toute façon.

Y a-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?

Répondre

138

Qu'en est-il de cette commande simple qui non seulement trouve mais efface la mauvaise nomenclature? :)

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

I love "trouver" :)

Avertissement Le ci-dessus modifier fichiers binaires qui contiennent ces trois caractères.

.

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

grep -rl $'\xEF\xBB\xBF' . 
+0

Brillant, monsieur ... merci! :-) – KyleFarris

+7

Détecte de manière incorrecte PDF avec un marqueur de nomenclature .. car il recherche tout le document, pas seulement la première ligne –

+8

Modifie les fichiers binaires ... –

7

Si vous acceptez des faux positifs (dans le cas où il y a des fichiers non texte, ou dans le cas peu probable il y a un espace insécable sans chasse au milieu d'un fichier), vous pouvez utiliser grep:

fgrep -rl `echo -ne '\xef\xbb\xbf'` . 
2
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 nulle séparés arguments au lieu de ligne séparés
  • grep -l répertorie les fichiers qui correspondent à l'expression rationnelle
  • Le regex ^\xeff\xbb\xbf n'est pas tout à fait correct, car il correspondra UTF-8 non BOMed fichiers s'ils ont des espaces largeur zéro au début d'une ligne
+0

Vous avez encore besoin d'une "tête 1" dans le tuyau avant le grep – MSalters

5

I utiliserait quelque chose comme:

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

Qui garantira que la nomenclature se produit à partir du premier octet du fichier.

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

La plupart des solutions données ci-dessus test plus que la première ligne du fichier, même si certains (comme Marcus solution) puis filtrer les résultats. Cette solution teste uniquement la première ligne de chaque fichier, ce qui devrait être un peu plus rapide.

+1

Got travaille avec ce qui suit sur Linux (RHEL6) - 'find.-type f -print0 | xargs -0 awk '/^\ xEF \ xBB \ xBF/{print FILENAME} {nextfile}' ' –

32

La meilleure et la plus simple de le faire sous Windows:

Total Commander → aller au répertoire racine du projet → trouver des fichiers (Alt + F7) → Types de fichiers * * → Rechercher du texte « EF BB. BF » → contrôle 'Hex' case → recherche

Et vous obtenez la liste :)

+1

Sympa, surtout l'utilisation de mon chef Total préféré depuis longtemps, mais malheureusement cela souffre le même problème que beaucoup d'autres: il recherche tous les octets dans un fichier, tant d'images, etc. Cela peut être légèrement amélioré en utilisant RegEx au lieu de Hex et en cherchant "^ \ xEF \ xBB \ xBF" qui éliminera beaucoup d'images mais qui a encore des fichiers qui ont la nomenclature à mi-chemin du fichier (bien qu'il devrait y en avoir peu) et bien sûr tous les fichiers binaires qui ont un code ASCII newline juste avant la BOM. Pourtant, toutes les images ont disparu dans ma recherche de test. – Legolas

4

Pour une Utilisateur Windows, voir this (bon script PHP pour trouver le BOM dans votre projet).

+0

Le site Web lié affiche: «Site Web hors connexion, aucune version en cache n'est disponible». – vog

+0

même script est également disponible dans github: http://github.com/emrahgunduz/BomCleaner – emrahgunduz

+0

Merci mon pote, Votre réponse a sauvé ma journée. –

3

Une solution surpuissant à c'est phptags (pas l'outil vi avec le même nom), qui porte spécifiquement pour les scripts PHP:

phptags --warn ./ 

Affichera quelque chose comme:

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

Et la Le mode --whitespace corrigera automatiquement ces problèmes (récursivement, mais affirme qu'il ne réécrit que les scripts .php.)

2

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

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \; 
5

Vous pouvez utiliser grep pour les trouver et Perl pour les dépouiller comme ceci:

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}' 
+0

Celui-ci a fonctionné pour moi, la réponse acceptée n'a pas (je suis sur un Mac) – mjsarfatti

0

Si vous cherchez des fichiers UTF, le file command travaux. Il vous dira quel est le codage du fichier. S'il y a des caractères non ASCII, il apparaîtra avec UTF.

file *.php | grep UTF 

Cela ne fonctionnera pas de manière récursive. Vous pouvez probablement truquer une commande de fantaisie pour la rendre récursive, mais j'ai juste cherché chaque niveau individuellement comme suit, jusqu'à ce que je manque de niveaux.

file */*.php | grep UTF 
Questions connexes