¿Cómo encontrar todos los archivos en el directorio que contiene BOM UTF-8 (marca de orden de bytes)?

8

En Windows, necesito encontrar todos los archivos en un directorio que contenga BOM UTF-8 (marca de orden de bytes). ¿Qué herramienta puede hacer eso y cómo?

Puede ser un script de PowerShell, la función de búsqueda avanzada de algún editor de texto o lo que sea.

Borek Bernard
fuente

Respuestas:

15

Aquí hay un ejemplo de un script de PowerShell. Busca en la C:ruta cualquier archivo donde estén los primeros 3 bytes 0xEF, 0xBB, 0xBF.

Function ContainsBOM
{   
    return $input | where {
        $contents = [System.IO.File]::ReadAllBytes($_.FullName)
        $_.Length -gt 2 -and $contents[0] -eq 0xEF -and $contents[1] -eq 0xBB -and $contents[2] -eq 0xBF }
}

get-childitem "C:\*.*" | where {!$_.PsIsContainer } | ContainsBOM

¿Es necesario "ReadAllBytes"? ¿Quizás leer unos pocos primeros bytes funcionaría mejor?

Punto justo. Aquí hay una versión actualizada que solo lee los primeros 3 bytes.

Function ContainsBOM
{   
    return $input | where {
        $contents = new-object byte[] 3
        $stream = [System.IO.File]::OpenRead($_.FullName)
        $stream.Read($contents, 0, 3) | Out-Null
        $stream.Close()
        $contents[0] -eq 0xEF -and $contents[1] -eq 0xBB -and $contents[2] -eq 0xBF }
}

get-childitem "C:\*.*" | where {!$_.PsIsContainer -and $_.Length -gt 2 } | ContainsBOM
vcsjones
fuente
1
Frio. Antes de marcar como respuesta, ¿es necesario "ReadAllBytes"? ¿Quizás leer unos pocos primeros bytes funcionaría mejor?
Borek Bernard
@Borek Ver edición.
vcsjones
2
Esto me salvó el día! También aprendí eso get-childitem -recursepara manejar subdirectorios también.
diynevala
Me preguntaba si hay una manera de eliminar las listas de materiales utilizando el script anterior.
tom_mai78101 06/0618
2

Como nota al margen, aquí hay un script de PowerShell que uso para quitar los caracteres BOM UTF-8 de mis archivos fuente:

$files=get-childitem -Path . -Include @("*.h","*.cpp") -Recurse
foreach ($f in $files)
{
(Get-Content $f.PSPath) | 
Foreach-Object {$_ -replace "\xEF\xBB\xBF", ""} | 
Set-Content $f.PSPath
}
Scott Smith
fuente
Acabo de recibir una gran cantidad de archivos que diferían solo por el hecho de que algunos tenían una lista de materiales y otros no. Tu respuesta fue justo lo que necesitaba para limpiarlo todo. ¡Gracias!
Tevya
1

Si está en una computadora empresarial (como yo) con privilegios restringidos y no puede ejecutar el script de PowerShell, puede usar un Notepad ++ portátil con el complemento PythonScript para realizar la tarea, con el siguiente script:

import os;
import sys;
filePathSrc="C:\\Temp\\UTF8"
for root, dirs, files in os.walk(filePathSrc):
    for fn in files:
      if fn[-4:] != '.jar' and fn[-5:] != '.ear' and fn[-4:] != '.gif' and fn[-4:] != '.jpg' and fn[-5:] != '.jpeg' and fn[-4:] != '.xls' and fn[-4:] != '.GIF' and fn[-4:] != '.JPG' and fn[-5:] != '.JPEG' and fn[-4:] != '.XLS' and fn[-4:] != '.PNG' and fn[-4:] != '.png' and fn[-4:] != '.cab' and fn[-4:] != '.CAB' and fn[-4:] != '.ico':
        notepad.open(root + "\\" + fn)
        console.write(root + "\\" + fn + "\r\n")
        notepad.runMenuCommand("Encoding", "Convert to UTF-8 without BOM")
        notepad.save()
        notepad.close()

El crédito va a https://pw999.wordpress.com/2013/08/19/mass-convert-a-project-to-utf-8-using-notepad/

Hoàng Long
fuente