Maneira elegante de pesquisar arquivos UTF-8 com BOM?
-
03-07-2019 - |
Pergunta
Para fins de depuração, preciso pesquisar recursivamente um diretório por todos os arquivos que começam com uma marca de pedidos de bytes 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 contêm uma quebra de linha, mas esses arquivos não devem ser esperados de qualquer maneira.
Existe alguma solução mais curta ou mais elegante?
Existem editores de texto ou macros interessantes para editores de texto?
Solução
Que tal esse comando simples que não apenas encontra, mas limpa o Nasty Bom? :)
find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;
Eu amo "Find" :)
AvisoO acima vai modificar Arquivos binários que contêm esses três caracteres.
.
Se você quiser apenas mostrar arquivos BOM, use este:
grep -rl $'\xEF\xBB\xBF' .
Outras dicas
A melhor e mais fácil maneira de fazer isso no Windows:
Comando total → Vá para o DIR da raiz do projeto → Encontre arquivos (Alt + F7) → Tipos de arquivo *.
E você recebe a lista :)
find . -type f -print0 | xargs -0r awk '
/^\xEF\xBB\xBF/ {print FILENAME}
{nextfile}'
A maioria das soluções fornecidas acima é mais do que a primeira linha do arquivo, mesmo que algumas (como a solução de Marcus) filtem os resultados. Esta solução testa apenas a primeira linha de cada arquivo, para que seja um pouco mais rápido.
Se você aceitar alguns falsos positivos (caso existam arquivos sem texto ou no caso improvável, haja um ZWNBSP no meio de um arquivo), você poderá usar o Grep:
fgrep -rl `echo -ne '\xef\xbb\xbf'` .
Eu usaria algo como:
grep -orHbm1 "^`echo -ne '\xef\xbb\xbf'`" . | sed '/:0:/!d;s/:0:.*//'
O que garantirá que o nascimento ocorra a partir do primeiro byte do arquivo.
Você pode usar grep
para encontrá -los e perl para retirá -los da mesma forma:
grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'
Para um usuário do Windows, veja isto (bom script PHP para encontrar o BOM
no seu projecto).
Uma solução de exagero para isso é phptags
(não o vi
ferramenta com o mesmo nome), que procura especificamente scripts PHP:
phptags --warn ./
Produzirá algo como:
./invalid.php: TRAILING whitespace ("?>\n")
./invalid.php: UTF-8 BOM alone ("\xEF\xBB\xBF")
E a --whitespace
O modo corrigirá automaticamente esses problemas (recursivamente, mas afirma que apenas reescreva scripts .php.)
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
find -print0
coloca um nulo 0 entre cada nome de arquivo em vez de usar novas linhasxargs -0
espera argumentos separados nulos em vez de linha separadosgrep -l
lista os arquivos que correspondem ao regex- O regex
^\xeff\xbb\xbf
não está totalmente correto, pois corresponderá aos arquivos UTF-8 não-bombas se tiverem espaços de largura zero no início de uma linha
Eu usei isso para corrigir apenas arquivos JavaScript:
find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
Se você está procurando arquivos UTF, o Comando de arquivo funciona. Ele dirá qual é a codificação do arquivo. Se houver algum caractere não ASCII lá, ele criará UTF.
file *.php | grep UTF
Isso não funcionará recursivamente. Você provavelmente pode montar um comando sofisticado para torná -lo recursivo, mas eu apenas pesquisei cada nível individualmente como o seguinte, até ficar sem níveis.
file */*.php | grep UTF