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
CRLF
como^M
::e ++ff=unix
. - Substituir todos os
^M
por^N
::s/\r/\r/
. - Remover
^M
só 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
dos2unix
docommunity
) -
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
).