À 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?
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' .
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 :)
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.
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'` .
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}{}'
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.
Pour un utilisateur Windows, consultez this (bon script PHP permettant de trouver le BOM
dans votre projet).
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.)
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 \;
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 lignesxargs -0
attend des arguments null séparés au lieu de séparer des lignesgrep -l
liste les fichiers qui correspondent à 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 ligneSi 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