it-swarm.dev

Maneira elegante de procurar por arquivos UTF-8 com BOM?

Para fins de depuração, preciso pesquisar recursivamente um diretório para todos os arquivos que começam com uma marca de ordem de byte UTF-8 (BOM). Minha solução atual é um script de shell simples:

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

Ou, se você preferir frases curtas e ilegíveis:

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

Ele não funciona com nomes de arquivos que contenham uma quebra de linha, , Mas esses arquivos não são esperados de qualquer maneira.

Existe alguma solução mais curta ou mais elegante?

Existem editores de texto ou macros interessantes para editores de texto?

83
vog

Que tal este comando simples que não apenas encontra, mas limpa o desagradável BOM? :)

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

Eu amo "encontrar" :)

Warning Os arquivos binários acima serão modify que contêm esses três caracteres.

.

Se você quiser apenas mostrar arquivos BOM, use este:

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

A maneira melhor e mais fácil de fazer isso no Windows:

Total Commander → vá para o diretório raiz do projeto → localizar arquivos (Alt + F7) → tipos de arquivos *. * → Localizar texto "EF BB BF" → marque a caixa 'Hex' → pesquisar

E você pega a lista :)

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

A maioria das soluções dadas acima testa mais do que a primeira linha do arquivo, mesmo que algumas (como a solução de Marcus) filtrem os resultados. Essa solução só testa a primeira linha de cada arquivo, portanto, deve ser um pouco mais rápida.

12
Aron Griffis

Se você aceitar alguns falsos positivos (no caso de haver arquivos que não sejam de texto, ou no caso improvável de haver um ZWNBSP no meio de um arquivo), você poderá usar o grep:

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

Você pode usar grep para encontrá-los e Perl para removê-los assim:

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

Eu usaria algo como:

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

O que garantirá que a lista de materiais ocorra a partir do primeiro byte do arquivo.

5
Marcus Griep

Para um usuário do Windows, consulte o script this (good PHP para localizar a BOM em seu projeto).

4
julien

Uma solução de overkill para isso é phptags (não a ferramenta vi com o mesmo nome), que procura especificamente por scripts PHP:

phptags --warn ./

Irá produzir algo como:

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

E o modo --whitespace corrigirá automaticamente tais problemas (recursivamente, mas afirma que apenas reescreve scripts .php).

3
mario

Eu usei isso para corrigir apenas os arquivos 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 coloca um valor nulo\0 entre cada nome de arquivo em vez de usar novas linhas
  • xargs -0 espera argumentos separados nulos em vez de separados por linha
  • grep -l lista os arquivos que correspondem ao regex
  • O regex ^\xeff\xbb\xbf não está totalmente correto, pois ele corresponderá a arquivos UTF-8 não-BOMeados se eles tiverem espaços de largura zero no início de uma linha
2
Jonathan Wright

Se você estiver procurando por arquivos UTF, o comando file works. Ele vai te dizer qual é a codificação do arquivo. Se houver algum caractere não ASCII, ele aparecerá com UTF.

file *.php | grep UTF

Isso não funcionará de forma recursiva. Provavelmente, você pode criar um comando sofisticado para torná-lo recursivo, mas eu pesquisei cada nível individualmente como o seguinte, até que fiquei sem níveis.

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