Convertendo em massa "end-of-line" de arquivos de texto entre Windows, GNU/Linux e Mac OS

Publicado por Luís Fernando C. Cavalheiro em 06/11/2013

[ Hits: 10.409 ]

Blog: https://github.com/lcavalheiro/

 


Convertendo em massa "end-of-line" de arquivos de texto entre Windows, GNU/Linux e Mac OS



Camaradinhas, aqui começa mais uma dica do Dino trazendo uns paranauês doidões do tempo em que o amigo Teixeira trabalhava nos ENIACs da vida.

Hoje, quero expandir a utilidade da dica:
Do amigo rcjeferson, trazendo um meio de realizar a dita conversão em massa entre os end-of-line do Windows, GNU/Linux e Mac OS.

Mas antes, vamos à uma conversinha: o que é o end-of-line? Bem, esse é o caractere que o sistema enfia no arquivo no momento em que você pressiona o Enter.

Quando algum outro programa "ler" o arquivo, ele vai encontrar o tal end-of-line e vai entender: "ah, aqui acaba o raio da linha, tenho que passar pra próxima".

Acontece que esses três sistemas operacionais não usam o mesmo end-of-line. O Windows, aferrado ao ASCII e às máquinas de Fax, usa os caracteres <CR> ("carriage return", ou "retorno de carro" - pensem naquele movimento que se precisa fazer ao chegar ao final da linha em uma máquina de escrever. E agora, reimaginem a cena sabendo que o nome daquela peça é carro) e <LF> ("line feed", que é o que abre a nova linha").

O GNU/Linux usa só o <LF>, e o Mac OS usa só o <CR>. Caos total, não é? Ainda mais se você é programador, usa mais de um sistema operacional e fica louquinho quando seu editor de textos estraga tudo.

Mas não se aflija, tudo que você precisa para a tarefa é o Vim. Isso mesmo, o Vim. Na maioria dos casos, isso significa que você não precisa instalar nada no seu computador. E se você não tem o Vim instalado, me dê seu endereço real que eu vou aí te cobrir de socos!

Um exemplo para explicar melhor:

find . -name "*txt" -execdir vi "{}" -c "set ff=dos" -c "wq" \;

Onde:
  • Procura todos os arquivos no diretório atual e subdiretórios dele, cujo nome termina em txt e aplica o comando: vi arquivo -c "set ff=dos" -c "wq" neles.
  • O name "*txt" é só um critério de busca, você pode usar qualquer um que lhe agrade (por exemplo: "-type f" para converter todos os arquivos, "-ctime" pra converter os mais recentes, etc.).
  • O pulo do gato é do -execdir pra frente: -execdir diz para executar o comando a seguir, como se ele fosse executado nativamente do diretório em que o arquivo se encontra. Útil em casos de árvores de diretórios complicadas;
  • "{}" (sim, entre aspas mesmo), serve para dizer ao comando (no caso, o vi) para agir sobre o arquivo localizado pelo find.
  • -c "set ff=dos" (aspas obrigatórias), indica que o vi deve aplicar o comando de modo normal (:set ff=dos) ao arquivo.
  • -c "wq" (aspas obrigatórias), indica que o vi deve aplicar o comando de modo normal (":wq") ao arquivo.

Mas o que fazem esses comandos de modo normal do Vi?

Bem, :set ff=string altera o end-of-line do arquivo, e string pode ser dos (<CR><LF> usado pelo Windows), Unix (<LF> usado pelo GNU/Linux) ou Mac (<CR> usado pelo MacOS).

Já o comando :wq salva e fecha o arquivo. Se o arquivo usar um end-of-line diferente do GNU/Linux, o próprio Vim te indicará isso ao pé da página, quando você abrir o arquivo, conforme você pode ver pelas screenshots a seguir (P.S.: não liguem pros textos, é coisa de RPGista):
Linux: Convertendo em massa end-of-line de arquivos de texto entre Windows, GNU/Linux e Mac OS   Linux: Convertendo em massa end-of-line de arquivos de texto entre Windows, GNU/Linux e Mac OS

Aqui mostra o set ff=mac. O GNU/Linux vai acusar que o arquivo está sem finais de linha (claro, não tem o <LF>). Caso você queira desfazer a caca, reinserindo os finais de linha em um arquivo com end-of-line do Mac OS, será preciso abrir o arquivo pelo Vim e rodar os comandos em modo normal:

:%s/^V^M/^V^M/g
:set ff=unix
:wq


Onde:
  • ^V significa: CTRL V
  • ^M significa: CTRL M

Bem, com esta pequena aula, de que nem sempre instalar um pacote adicional é a melhor saída quando a gambiarra está à disposição, o Dino se despede desejando a todos vocês um bom final de Samhain (o festejo, não o dia, vai do dia 31/10 ao 02/11), um ótimo desaniversário amanhã e uma "quentíssima" amante zumbi!

Outras dicas deste autor

Instalação do VLC no openSUSE Tumbleweed usando o repositório da VideoLAN

Criando o comando grub-update no Fedora

Corrigindo instabilidade de conexão das placas de rede wireless Realtek RTL8188xx/8192xx/8723xx/8821xx

Fazendo o right-click do touchpad funcionar no GNOME

Para os gamers: acessando Gearbox SHiFT no GNU/Linux

Leitura recomendada

Adicionando e apagando usuários no OpenBSD

Comando watch com saída em cores

Comando ifconfig no Debian 10

Comandos de manipulação de arquivos e diretórios

Descobrindo daemons (servidores) rodando em background

  

Comentários
[1] Comentário enviado por leandro em 07/11/2013 - 20:19h

Como costumo editar arquivos para serem abertos em outros sistemas, sempre tenho que ficar convertendo antes.

Para ajudar, eu monitoro qual é o fim de linha + a codificação do arquivo pela barra de status:

set laststatus=2
set statusline=%f\ %m%r%h%w\ %=\ [TIPO=%Y]\ [COD=%{strlen(&fenc)?&fenc:'none'}/%{&ff}]\ [LN=%L]

E ao salvar um arquivo, eu converto antes a codificação/fim de linha com a função:

function! Encoding(type)
if a:type == "dos"
set fileencoding=iso-8859-1
set fileformat=dos
elseif a:type == "unix"
set fileencoding=utf=8
set fileformat=unix
endif
endfunction


Usando:

:call Encoding("dos")
:call Encoding("unix")

Funciona bem para arquivos únicos. Mas para vários arquivos, a sua solução é a ideal.

Favoritada!

[2] Comentário enviado por rcjeferson em 07/11/2013 - 23:32h

Muito boa sua dica lcavalheiro, sensacional.

Parabens!

[3] Comentário enviado por lcavalheiro em 08/11/2013 - 09:31h


[1] Comentário enviado por leandro em 07/11/2013 - 20:19h:

Como costumo editar arquivos para serem abertos em outros sistemas, sempre tenho que ficar convertendo antes.

Para ajudar, eu monitoro qual é o fim de linha + a codificação do arquivo pela barra de status:

set laststatus=2
set statusline=%f\ %m%r%h%w\ %=\ [TIPO=%Y]\ [COD=%{strlen(&fenc)?&fenc:'none'}/%{&ff}]\ [LN=%L]

E ao salvar um arquivo, eu converto antes a codificação/fim de linha com a função:

function! Encoding(type)
if a:type == "dos"
set fileencoding=iso-8859-1
set fileformat=dos
elseif a:type == "unix"
set fileencoding=utf=8
set fileformat=unix
endif
endfunction


Usando:

:call Encoding("dos")
:call Encoding("unix")

Funciona bem para arquivos únicos. Mas para vários arquivos, a sua solução é a ideal.

Favoritada!


Leandro, dá para usar sua função com esta dica. A linha de comando ficaria:
$ find . -name "*txt" -execdir vi "{}" -c 'call Encoding("dos")' -c "wq" \;

O parâmetro -c na linha de comando diz ao vi que ele tem que usar o argumento do parâmetro como um comando de modo normal, logo ele vai chamar sua função e fazer essa graça toda. Só que como a função usa aspas será preciso limitar o argumento do parâmetro com aspas simples.


[2] Comentário enviado por rcjeferson em 07/11/2013 - 23:32h:

Muito boa sua dica lcavalheiro, sensacional.

Parabens!


Valeu, cara!

[4] Comentário enviado por SuperSlackware em 06/07/2017 - 15:13h

Obrigado Dino, salvou o meu dia essa Hiper, Mega Dica.
Muito Grato



Contribuir com comentário