Usar o awk para remover a marca de 'Byte-order'
como seria um script {[[0]} (presumivelmente um liner) para remover um BOM ?
Especificação:
- imprime todas as linhas após a primeira (
NR > 1
) - para a primeira linha: se começar por
#FE #FF
ou#FF #FE
, remova esses e imprima o resto
5 answers
Tenta isto:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}{print}' INFILE > OUTFILE
No primeiro registo (linha), remova os caracteres BOM. Imprime todos os discos.
Ou um pouco mais curto, usando o conhecimento de que a acção por omissão no awk é imprimir o registo:
awk 'NR==1{sub(/^\xef\xbb\xbf/,"")}1' INFILE > OUTFILE
1
é a condição mais curta que sempre avalia a verdade, então cada registro é impresso.
-- adenda --
A marca de ordem de bytes Unicode (BOM) FAQ inclui a seguinte tabela listando o BOM EXACTO 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 \xef\xbb\xbf
corresponde a EF BB BF
UTF-8
BOM bytes da tabela acima.
Usando o GNU sed
(no Linux ou no 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 FreeBSD sed
: o parâmetro -i
significa "no lugar", e irá atualizar arquivos sem a necessidade de redireções ou truques estranhos.
Em Mac:
Esta solução awk
em outra resposta funciona, mas o comando sed
acima não funciona. Pelo menos em Mac (Sierra) sed
a documentação não menciona o suporte à fuga de ala em hexadecimal. \xef
.
Um truque semelhante pode ser alcançado com qualquer programa através de piping 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 o BOM:
hd -n 3 UTF8
Se o BOM estiver presente verás: 00000000 ef bb bf ...
Para além de converter as terminações de linha CRLF para LF, {[2] } também remove os Homs:
dos2unix *.txt
dos2unix
também converte os ficheiros UTF-16 com um BOM (mas não os ficheiros UTF-16 sem um BOM) para UTF-8 sem um 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 foi dirigida ao unix/linux, pensei que valeria a pena mencionar uma boa opção para o Unix-challenged (no windows, com um UI).
Eu corri para o mesmo problema em um projeto WordPress (BOM estava causando problemas com o feed rss e validação de página) e eu tive que olhar para todos os arquivos em uma árvore de diretório bastante grande para encontrar o que estava com BOM. Encontrei uma aplicação chamada substituir o Pioneer e nela:
Batch Runner - > Search (para encontrar todos os ficheiros nas sub-pastas) - > substituir o modelo - > remover binário BOM (existe um modelo de procura e substituição pronto para isto).
Não foi a solução mais elegante e exigiu a instalação de um programa, que é uma desvantagem. Mas uma vez que eu descobri o que estava acontecendo ao meu redor, ele funcionou como um encanto (e encontrou 3 arquivos de cerca de 2300 que estavam com BOM).