Pergunta

Como é que um script awk (presumivelmente um one-liner) para a remoção de um olhar BOM como ?

Especificação:

  • imprimir cada linha após a primeira (NR > 1)
  • para a primeira linha: Se ele começa com #FE #FF ou #FF #FE, remover aqueles e imprimir o resto
Foi útil?

Solução

Tente isto:

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE

No primeiro registro (linha), remova os caracteres BOM. Imprimir cada registro.

Ou um pouco mais curto, usando o conhecimento de que a ação padrão em awk é imprimir o registro:

awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE

1 é a condição mais curto que sempre avalia a verdade, de modo que cada registro é impresso.

Aproveite!

- ADENDO -

Unicode Byte Order Mark (BOM) FAQ inclui o seguinte tabela listando o BOM exata bytes para cada codificação:

Bytes         |  Encoding Form
--------------------------------------
00 00 FE FF   |  UTF-32, big-endian
FF FE 00 00   |  UTF-32, little-endian
FE FF         |  UTF-16, big-endian
FF FE         |  UTF-16, little-endian
EF BB BF      |  UTF-8

Assim, você pode ver como corresponde \xef\xbb\xbf para EF BB BF UTF-8 BOM bytes da tabela acima.

Outras dicas

Usando GNU sed (no Linux ou Cygwin):

# Removing BOM from all text files in current directory:
sed -i '1 s/^\xef\xbb\xbf//' *.txt

No FreeBSD:

sed -i .bak '1 s/^\xef\xbb\xbf//' *.txt

Vantagem de usar GNU ou sed FreeBSD:. Os meios de parâmetros -i "no lugar", e irá atualizar arquivos sem a necessidade de redirecionamentos ou truques estranhos

No Mac:

Esta solução awk em outra resposta funciona , mas o comando sed acima não funciona. Pelo menos no Mac (Serra) documentação sed não menciona apoio hexadecimal escapar ala \xef.

Um truque semelhante pode ser alcançado com qualquer programa, canalizando para a ferramenta sponge de moreutils :

awk '…' INFILE | sponge INFILE

Não awk, mas mais simples:

tail -c +4 UTF8 > UTF8.nobom

Para verificar se há BOM:

hd -n 3 UTF8

Se BOM está presente você verá: 00000000 ef bb bf ...

Além de converter finais de linha CRLF para LF, dos2unix também remove BOMs:

dos2unix *.txt

dos2unix também converte UTF-16 arquivos com um BOM (mas não UTF-16 arquivos sem BOM) para UTF-8 sem BOM:

$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16be>bom-utf16be
$ printf '\ufeffä\n'|iconv -f utf-8 -t utf-16le>bom-utf16le
$ printf '\ufeffä\n'>bom-utf8
$ printf 'ä\n'|iconv -f utf-8 -t utf-16be>utf16be
$ printf 'ä\n'|iconv -f utf-8 -t utf-16le>utf16le
$ printf 'ä\n'>utf8
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be feff00e4000a
bom-utf16le fffee4000a00
   bom-utf8 efbbbfc3a40a
    utf16be 00e4000a
    utf16le e4000a00
       utf8 c3a40a
$ dos2unix -q *
$ for f in *;do printf '%11s %s\n' $f $(xxd -p $f);done
bom-utf16be c3a40a
bom-utf16le c3a40a
   bom-utf8 c3a40a
    utf16be 00e4000a
    utf16le e4000a00
       utf8 c3a40a

Eu sei que a pergunta era dirigida a unix / linux, pensei que seria interessante mencionar uma boa opção para o unix-desafiado (no Windows, com uma UI).
Corri para o mesmo problema em um projeto WordPress (BOM estava causando problemas com a alimentação de RSS e validação da página) e eu tive que olhar para todos os arquivos em uma árvore de diretórios muito grande para encontrar o que estava com BOM. Encontrou um aplicativo chamado Substituir Pioneer e nele:

Batch Runner -> Search (para encontrar todos os arquivos nas subpastas) -> Substituir Modelo -> BOM Binary remove (há um pronto-procurar e substituir modelo para isso).

Não era a solução mais elegante e que exigia a instalação de um programa, que é uma desvantagem. Mas uma vez que eu descobri o que estava acontecendo ao meu redor, ele trabalhou como um encanto (e encontrou 3 arquivos de cerca de 2300 que estavam com BOM).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top