Você pode usar
LANG=C LC_ALL=C sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- filename
para remover a marca de ordem de byte do início do arquivo, se houver, bem como converter qualquer nova linha CR LF para LF apenas. O LANG=C LC_ALL=C
informa ao shell que você deseja que o comando seja executado na localidade C padrão (também conhecida como o código de idioma POSIX padrão), em que os três bytes que formam a Marca de Ordem de Byte são tratados como bytes. A opção -i
para sed significa in loco. Se você usar -i.old
, o sed salvará o arquivo original como filename.old
e o novo arquivo (com as modificações, se houver) como filename
.
Eu pessoalmente gosto de ter isso como ~/bin/fix-ms
; por exemplo, como
#!/bin/dash
export LANG=C LC_ALL=C
if [ $# -gt 0 ]; then
for FILE in "$@" ; do
sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//' -i -- "$FILE" || exit 1
done
else
exec sed -e 's/\r$// ; 1 s/^\xef\xbb\xbf//'
fi
para que, se eu precisar aplicar isso para dizer todos os arquivos-fonte e cabeçalhos C (meu código antigo da era do MS-DOS, por exemplo!), eu simplesmente corro
find . -name '*.[CHch]' -print0 | xargs -r0 ~/bin/ms-fix
ou, se eu quiser apenas olhar para esse arquivo, sem modificá-lo, posso executar
~/bin/ms-fix < filename | less
e não ver o feio <U+FEFF>
no meu terminal UTF-8.