Remover CRLF

Para manter o padrão utilizado nos antigos Teletipos, o
DOS/Windows utiliza dois caracteres de controle para representar uma quebra de linha, um
Carriage Return (CR = 0x0D) e um
Line Feed (LF = 0x0A), porém sistemas Unix-Like
perceberam que isso era um desperdício de 1 byte por linha e bastava um LF para representar uma nova
linha.
Exemplo:
$ cat bacon.txt
Bacon Ipsum:
Bacon ipsum dolor sit amet salami
pork belly tail tongue pancetta,
pork loin tri-tip drumstick bresaola shankle.
$ file bacon_windows.txt bacon_linux.txt
bacon_windows.txt: ASCII text, with CRLF line terminators
bacon_linux.txt: ASCII text
$ hexdump -C bacon_linux.txt
00000000 42 61 63 6f 6e 20 49 70 73 75 6d 3a <strong>0a 0a</strong> 42 61 |Bacon Ipsum:..Ba|
00000010 63 6f 6e 20 69 70 73 75 6d 20 64 6f 6c 6f 72 20 |con ipsum dolor |
00000020 73 69 74 20 61 6d 65 74 20 73 61 6c 61 6d 69 <strong>0a</strong> |sit amet salami.|
00000030 70 6f 72 6b 20 62 65 6c 6c 79 20 74 61 69 6c 20 |pork belly tail |
00000040 74 6f 6e 67 75 65 20 70 61 6e 63 65 74 74 61 2c |tongue pancetta,|
00000050 <strong>0a</strong> 70 6f 72 6b 20 6c 6f 69 6e 20 74 72 69 2d 74 |.pork loin tri-t|
00000060 69 70 20 64 72 75 6d 73 74 69 63 6b 20 62 72 65 |ip drumstick bre|
00000070 73 61 6f 6c 61 20 73 68 61 6e 6b 6c 65 2e <strong>0a</strong> |saola shankle..|
0000007f
$ hexdump -C bacon_windows.txt
00000000 42 61 63 6f 6e 20 49 70 73 75 6d 3a <strong>0d 0a 0d 0a</strong> |Bacon Ipsum:....|
00000010 42 61 63 6f 6e 20 69 70 73 75 6d 20 64 6f 6c 6f |Bacon ipsum dolo|
00000020 72 20 73 69 74 20 61 6d 65 74 20 73 61 6c 61 6d |r sit amet salam|
00000030 69 <strong>0d 0a</strong> 70 6f 72 6b 20 62 65 6c 6c 79 20 74 61 |i..pork belly ta|
00000040 69 6c 20 74 6f 6e 67 75 65 20 70 61 6e 63 65 74 |il tongue pancet|
00000050 74 61 2c <strong>0d 0a</strong> 70 6f 72 6b 20 6c 6f 69 6e 20 74 |ta,..pork loin t|
00000060 72 69 2d 74 69 70 20 64 72 75 6d 73 74 69 63 6b |ri-tip drumstick|
00000070 20 62 72 65 73 61 6f 6c 61 20 73 68 61 6e 6b 6c | bresaola shankl|
00000080 65 2e <strong>0d 0a</strong> |e...|
00000084
Perceba que o arquivo criado no Windows contém a sequência 0d 0a nos lugares onde o arquivo criado
no Linux aparece apenas 0a. É claro que isso ia trazer problemas de compatibilidade e dores de
cabeça.
Apesar de bons editores conseguirem trabalhar com ambos os arquivos (no Notepad as linhas do
bacon_linux.txt aparecerão todas concatenadas), arquivos que supostamente deveriam ser iguais
aparecem como diferentes se usarmos ferramentas como o “diff”:
$ diff bacon_windows.txt bacon_linux.txt
1,5c1,5
< Bacon Ipsum:
<
< Bacon ipsum dolor sit amet salami
< pork belly tail tongue pancetta,
< pork loin tri-tip drumstick bresaola shankle.
---
> Bacon Ipsum:
>
> Bacon ipsum dolor sit amet salami
> pork belly tail tongue pancetta,
> pork loin tri-tip drumstick bresaola shankle.
Hoje coloquei alguns códigos feitos parte no Windows e parte no Linux em controle de versão e preferi padronizar tudo para usar apenas o LF. Aqui mostrarei como fiz a conversão automaticamente pelo Linux:
Vim
Duas formas:
1
- Exibir
CRLFcomo^M::e ++ff=unix. - Substituir todos os
^Mpor^N::s/\r/\r/. - Remover
^Msó se ele estiver no fim da linha::s/\r\+$// - Remover todos os
^M::s/^M//
^M é digitado como ^V^M (ctrl+V ctrl+M).
2
- Converter o formato do arquivo para unix:
:setlocal fileformat=unix - Salvar:
:w - Recarregar:
:e
Converter vários arquivos
- Assume formato DOS:
:set ffs=dos. - Lista de arquivos a serem convertidos:
:args *.c *.h. - Altera o formato de cada argumento:
:argdo set ff=unix|w.
Outros comandos úteis: :set list e :set nobomb.
sed
sed, Stream EDitor, é um dos utilitários de linha de comando mais úteis para processar texto.
Ele trabalha linha a linha, então, se soubermos que o arquivo está no formato DOS podemos usar o
sed para substituir os dois últimos caracteres (CRLF = /r/n) de cada linha por apenas LF (/n):
sed -i 's/.$//' arquivo.txt
Mas tome cuidado, pois se o arquivo já estiver no formato Unix, você vai acabar apagando o último caractere de cada linha.
O caminho contrário, converter um arquivo para o formato DOS, também pode ser feito com o GNU sed:
sed -i 's/$/\r/' arquivo.txt
Tofrodos
Se você não quiser se preocupar em verificar se o arquivo já segue o padrão Unix, uma alternativa ao
sed é o Tofrodos. Se o arquivo já estiver convertido ele simplesmente deixa-o como está, isso é
especialmente útil em scripts.
Baixe e instale o Tofrodos, disponível no AUR. (Ou o
dos2unixdocommunity)Execute o seguinte comando na pasta que irá para o controle de versão (onde
^MéCtrl+V+Ctrl+M):grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'
Este comando irá converter todos os CR+LF para LF em todos os arquivos da pasta atual e das
subpastas.
Troque fromdos por todos para fazer a conversão contrária (LF para CR+LF).
Links

Sou um engenheiro de computação brasileiro baseado na Alemanha, apaixonado por tecnologia, ciência, fotografia e línguas.
Programo há cerca de duas décadas, explorando desde aplicativos móveis e desenvolvimento web até aprendizado de máquina. Atualmente, foco em SRE de nuvem e engenharia de dados.
Sou voluntário nas comunidades de open source e Python, ajudando a organizar a PyCon DE e a PyData Berlin, mentorando e contribuindo com código e traduções.
No meu blog, compartilho dicas de Linux, guias de configuração e notas pessoais que escrevo para referência futura. Espero que outras pessoas também as considerem úteis. O conteúdo está disponível em vários idiomas.
Visite minha galeria para ver algumas das minhas fotografias.
Longe do teclado, você vai me encontrar em shows, tocando clarinete, pedalando, mergulhando ou explorando novos lugares, culturas e culinárias.
Sempre feliz em me conectar! 🙂