2008-10-15 26 views
78

Para fines de depuración, necesito buscar recursivamente en un directorio todos los archivos que comienzan con una marca de orden de bytes UTF-8 (BOM). Mi solución actual es un simple script de shell:¿Manera elegante de buscar archivos UTF-8 con BOM?

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

O, si lo prefiere, ilegibles cortos de una sola línea:

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

No funciona con nombres de archivo que contienen un salto de línea, pero tales archivos no son de esperar de todos modos.

¿Hay alguna solución más corta o más elegante?

¿Hay editores de texto o macros interesantes para los editores de texto?

Respuesta

138

¿Qué tal este simple comando que no solo encuentra sino que borra la desagradable LDM? :)

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

Me encanta "encontrar" :)

Advertencia Lo anterior se modificar archivos binarios que contienen esos tres caracteres.

.

Si desea sólo para mostrar los archivos de lista de materiales, utilice la siguiente:

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

Brillante, señor ... gracias! :-) – KyleFarris

+7

Detecta incorrectamente PDF con un marcador BOM ... eso es porque busca todo el documento, no solo la primera línea –

+8

Modifica los archivos binarios ... –

7

Si acepta algunos falsos positivos (por si hay archivos que no son de texto, o en el caso poco probable hay una ZWNBSP en medio de un archivo), puede utilizar 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 pone un nulo \ 0 entre cada nombre de archivo en lugar de utilizar las nuevas líneas
  • xargs -0 Espera nulos argumentos separados en lugar de la línea separados
  • grep -l enumera los archivos que coinciden con la expresión regular
  • ^\xeff\xbb\xbf la expresión regular no es del todo correcto, ya que coincidirá no BOMED UTF-8 archivos si tienen cero espacios de anchura en el inicio de una línea
+0

usted todavía tiene una "cabeza 1" en la tubería antes de que el grep – MSalters

5

I usaría algo como:

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

Lo que asegurará que la BOM ocurra comenzando en el primer byte del archivo.

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

La mayoría de las soluciones dadas anteriormente prueba más de la primera línea del archivo, aunque algunos (como Marcus solución) luego filtra los resultados. Esta solución solo prueba la primera línea de cada archivo, por lo que debería ser un poco más rápido.

+1

Got está trabajando con lo siguiente en Linux (RHEL6) - 'find.-type f -print0 | xargs -0 awk '/^\ xEF \ xBB \ xBF/{print FILENAME} {nextfile}' ' –

32

La forma mejor y más fácil de hacer esto en Windows:

Total Commander → ir al directorio raíz del proyecto → encontrar archivos (Alt + F7) → tipos de archivos * * → Buscar texto "EF BB. BF" casilla de verificación → 'Hex' → búsqueda

Y se obtiene la lista :)

+1

Agradable, especialmente el uso de mi comandante total favorito durante mucho tiempo, pero desafortunadamente esto sufre el mismo problema que muchos otros: busca todos los bytes en un archivo, se informan tantas imágenes, etc. Esto se puede mejorar ligeramente usando RegEx en lugar de Hex y buscando "^ \ xEF \ xBB \ xBF" que eliminará muchas imágenes pero aún tiene archivos que tienen la BOM a la mitad del archivo (aunque debería haber pocos) y por supuesto cualquier archivo binario que tenga un código de ascii newline justo antes de la BOM. Aún así, todas las imágenes desaparecieron en mi búsqueda de prueba. – Legolas

4

Para una Usuario de Windows, vea this (buen script PHP para encontrar el BOM en su proyecto).

+0

El sitio web vinculado muestra: "Sitio web fuera de línea, sin versión en caché disponible". – vog

+0

mismo script también está disponible en github: http://github.com/emrahgunduz/BomCleaner – emrahgunduz

+0

Gracias amigo, Tu respuesta me salvó el día. –

3

Una solución exageración de esto es phptags (no la herramienta vi con el mismo nombre), que busca específicamente scripts PHP:

phptags --warn ./ 

seria algo como:

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

Y el El modo --whitespace corregirá automáticamente dichos problemas (recursivamente, pero afirma que solo reescribe scripts .php).

2

He utilizado este para corregir sólo los archivos de JavaScript:

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

Puede utilizar grep para encontrarlos y Perl para despojar a cabo de esta manera:

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

Este me funcionó, la respuesta aceptada no (estoy en una Mac) – mjsarfatti

0

Si está buscando archivos UTF, la file command trabajos. Te dirá cuál es la codificación del archivo. Si hay caracteres no ASCII allí, aparecerá UTF.

file *.php | grep UTF 

Eso no funcionará recursivamente. Probablemente pueda improvisar un comando elegante para hacerlo recursivo, pero solo busqué cada nivel individualmente como el siguiente, hasta que me quede sin niveles.

file */*.php | grep UTF 
Cuestiones relacionadas