it-swarm.dev

Adicionando BOM a arquivos UTF-8

Eu estou procurando (sem sucesso) por um script, que funcionaria como um arquivo de lote e me permite prefixar um arquivo de texto UTF-8 com um BOM, se ele não tiver um.

Nem a linguagem em que está escrito (Perl, python, c, bash) nem o SO em que funciona, são importantes para mim. Eu tenho acesso a uma ampla gama de computadores.

Eu encontrei um monte de scripts para fazer o contrário (tira o BOM), o que me parece um pouco bobo, como muitos programa do Windows terá problemas para ler arquivos de texto UTF-8, se eles não têm um BOM.

Eu senti falta do óbvio?

Obrigado!

33
Stephane

Eu escrevi este addbom.sh usando o comando 'file' e o comando ICU 's' uconv '.

#!/bin/sh

if [ $# -eq 0 ]
then
        echo usage $0 files ...
        exit 1
fi

for file in "[email protected]"
do
        echo "# Processing: $file" 1>&2
        if [ ! -f "$file" ]
        then
                echo Not a file: "$file" 1>&2
                exit 1
        fi
        TYPE=`file - < "$file" | cut -d: -f2`
        if echo "$TYPE" | grep -q '(with BOM)'
        then
                echo "# $file already has BOM, skipping." 1>&2
        else
                ( mv "${file}" "${file}"~ && uconv -f utf-8 -t utf-8 --add-signature < "${file}~" > "${file}" ) || ( echo Error processing "$file" 1>&2 ; exit 1)
        fi
done

edit: Adicionado citações em torno dos argumentos mv. Obrigado @DirkR e feliz por este script ter sido tão útil!

41
Steven R. Loomis

A maneira mais fácil que encontrei para isso é 

#!/usr/bin/env bash

#Add BOM to the new file
printf '\xEF\xBB\xBF' > with_bom.txt

# Append the content of the source file to the new file
cat source_file.txt >> with_bom.txt

Eu sei que ele usa um programa externo (cat) ... mas ele fará o trabalho facilmente no bash

Testado no osx, mas também deve funcionar no linux

OBSERVAÇÃO que pressupõe que o arquivo ainda não possui o BOM (!)

25
Yaron U.

(Resposta baseada em https://stackoverflow.com/a/9815107/1260896 por yingted)

Para adicionar BOMs a todos os arquivos que começam com "foo-", você pode usar sed. sed tem uma opção para fazer um backup.

sed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' foo-*

Se você tiver certeza de que não há BOM, simplifique o comando:

sed -i '1s/^/\xef\xbb\xbf/' foo-*

Certifique-se de que você precisa configurar o UTF-8, porque, por exemplo, o UTF-16 é diferente (caso contrário, verifique Como posso adicionar novamente um marcador de ordem de byte unicode no linux? )

10
Franklin Piat

Eu acho muito simples. Assumindo que o arquivo é sempre UTF-8 (você não está detectando a codificação, você sabe a codificação):

Leia os três primeiros caracteres. Compare-os com a seqüência de BOM do UTF-8 (a Wikipédia diz que é 0xEF, 0xBB, 0xBF). Se for o mesmo, imprima-os no novo arquivo e copie todo o resto do arquivo original para o novo arquivo. Se for diferente, primeiro imprima a lista de materiais e, em seguida, imprima os três caracteres e, em seguida, imprima tudo o mais do arquivo original para o novo arquivo.

Em C, fopen/fclose/fread/fwrite deve ser suficiente.

4
luiscubal

Como uma melhoria na solução da Yaron U., você pode fazer tudo em uma única linha:

printf '\xEF\xBB\xBF' | cat - source.txt > source-with-bom.txt

O bit cat - diz para concatenar na frente de source.txt o que está sendo enviado do comando print. Testado no OS X e no Ubuntu.

2
Trenton
0
Vdragon