Uma forma elegante de procurar por ficheiros UTF-8 com o BOM?
para efeitos de depuração, preciso de procurar recursivamente numa pasta por todos os ficheiros que comecem por uma marca de ordem de bytes UTF-8 (BOM). A minha solução actual é um script de consola 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 preferir camisas curtas e ilegíveis:
find -type f|while read file;do [ "`head -c3 -- "$file"`" == $'\xef\xbb\xbf' ] && echo "found BOM in: $file";done
Não funciona com nomes de ficheiros que contêm uma quebra de linha,
mas esses arquivos não são de esperar de qualquer maneira.
Há alguma solução mais curta ou mais elegante?
Existem alguns editores de texto interessantes ou macros para editores de texto?
11 answers
find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;
Adoro "encontrar".
Atenção o acima irá modificar os ficheiros binários que contêm esses três caracteres.
.
Se quiser apenas mostrar os ficheiros BOM, use este:
grep -rl $'\xEF\xBB\xBF' .
A melhor e mais fácil maneira de fazer isto no Windows:
Total Commander → go to project's root dir → find files (Alt + F7) → tipos de ficheiros *.* → Encontre o texto "EF BB BF "→ verifique' Hex ' checkbox → search
E tu ficas com a lista:)
find . -type f -print0 | xargs -0r awk '
/^\xEF\xBB\xBF/ {print FILENAME}
{nextfile}'
A maioria das soluções dadas acima testam mais do que a primeira linha do arquivo, mesmo que alguns (como a solução de Marcus) filtrem os resultados. Esta solução só testa a primeira linha de cada arquivo, por isso deve ser um pouco mais rápido.
Se aceitar alguns falsos positivos( no caso de existirem ficheiros Não-texto, ou no caso improvável de existir um ZWNBSP no meio de um ficheiro), 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 assegurará que o BOM ocorra a partir do primeiro byte do ficheiro.
Podes usar grep
Para Os encontrar e o Perl para os despir assim:
grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'
Para um utilizador do Windows, Veja Este (bom programa de PHP para encontrar o BOM
no seu projecto).
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
irá corrigir automaticamente tais problemas (recursivamente, mas afirma que só reescreve .scripts php.)
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
-
find -print0
coloca um null \0 entre cada nome de ficheiro em vez de usar novas linhas -
xargs -0
espera argumentos separados por nulos em vez de linhas separadas -
grep -l
lista os ficheiros que correspondem à expressão regular - a expressão regular
^\xeff\xbb\xbf
não está inteiramente correcta, uma vez que irá corresponder a ficheiros UTF-8 não instruídos, se tiverem espaços de largura zero no início de uma linha
Usei isto para corrigir apenas ficheiros JavaScript:
find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
Se estiver à procura de ficheiros UTF, o comando ficheiro funciona. Ele lhe dirá qual é a codificação do arquivo. Se houver algum caráteres não ASCII em lá ele virá acima com UTF.
file *.php | grep UTF
Mas isso não vai funcionar recursivamente. Você pode provavelmente montar algum comando chique para torná-lo recursivo, mas eu apenas procurei cada nível individualmente como o seguinte, até que eu fiquei sem níveis.
file */*.php | grep UTF